Is it possible to get scenario inside the step in Cucumber? - java

I need to make screenshot inside the step on specific place. It means not on #BeforeStep nor on #AfterStep. I need to call
// public void someStep(Scenario scenario) // This does not work
public void someStep()
{
page.openUrl();
scenario.attach(screenshot(), "image/png", fileName1);
page.doSomething();
scenario.attach(screenshot(), "image/png", fileName2);
page.doSomethingElse();
}
But I am not able to get current scenario related to the step execution. Is it possible or not? I tried to call it like someStep(Scenarion scenario) but it throws an error.

If you want access to the scenario object, your best bet is an AfterStep hook. However this is not supported in all flavours of cucumber. Your best bet is to check the docs or API documentation for your language

Related

JUnit - How to unit test method that reads files in a directory and uses external libraries

I have this method that I am using in a NetBeans plugin:
public static SourceCodeFile getCurrentlyOpenedFile() {
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
/* Get Java file currently displaying in the IDE if there is an opened project */
if (openedProject != null) {
TopComponent activeTC = TopComponent.getRegistry().getActivated();
DataObject dataLookup = activeTC.getLookup().lookup(DataObject.class);
File file = FileUtil.toFile(dataLookup.getPrimaryFile()); // Currently opened file
// Check if the opened file is a Java file
if (FilenameUtils.getExtension(file.getAbsoluteFile().getAbsolutePath()).equalsIgnoreCase("java")) {
return new SourceCodeFile(file);
} else {
return null;
}
} else {
return null;
}
}
Basically, using NetBeans API, it detects the file currently opened by the user in the IDE. Then, it loads it and creates a SourceCodeFile object out of it.
Now I want to unit test this method using JUnit. The problem is that I don't know how to test it.
Since it doesn't receive any argument as parameter, I can't test how it behaves given wrong arguments. I also thought about trying to manipulate openedProject in order to test the method behaviour given some different values to that object, but as far as I'm concernet, I can't manipulate a variable in JUnit that way. I also cannot check what the method returns, because the unit test will always return null, since it doesn't detect any opened file in NetBeans.
So, my question is: how can I approach the unit testing of this method?
Well, your method does take parameters, "between the lines":
MainProjectManager mainProjectManager = new MainProjectManager();
Project openedProject = mainProjectManager.getMainProject();
basically fetches the object to work on.
So the first step would be to change that method signature, to:
public static SourceCodeFile getCurrentlyOpenedFile(Project project) {
...
Of course, that object isn't used, except for that null check. So the next level would be to have a distinct method like
SourceCodeFile lookup(DataObject dataLookup) {
In other words: your real problem is that you wrote hard-to-test code. The "default" answer is: you have to change your production code, to make easier to test.
For example by ripping it apart, and putting all the different aspects into smaller helper methods.
You see, that last method lookup(), that one takes a parameter, and now it becomes (somehow) possible to think up test cases for this. Probably you will have to use a mocking framework such as Mockito to pass mocked instances of that DataObject class within your test code.
Long story short: there are no detours here. You can't test your code (in reasonable ways) as it is currently structured. Re-structure your production code, then all your ideas about "when I pass X, then Y should happen" can work out.
Disclaimer: yes, theoretically, you could test the above code, by heavily relying on frameworks like PowerMock(ito) or JMockit. These frameworks allow you to contol (mock) calls to static methods, or to new(). So they would give you full control over everything in your method. But that would basically force your tests to know everything that is going on in the method under test. Which is a really bad thing.

How to embed a screenshot in Cucumber report for each action taken?

I see a post was made for this here How to capture a screenshot after each step in tests with JAVA and Cucumber?
But, what I would like to do is be able to take a screenshot after every single action taken even within a single Cucumber step and embed into the Cucumber report. In other words, there are multiple actions taken in a single step to satisfy that step and I would like to embed the screenshot for all of them. Is this possible? If so, how?
You can use the #BeforeStep or #AfterStep cucumber annotation in your hook class and then call you screenshot method inside it.
public class Hooks{
#BeforeStep
public void beforeEachStep(){
takeScreenshot();
}
}

Test Case to make sure data cannot be loaded

I have a test case I'm trying to finish. It should try to find location ABC, but that doesn't actually exist in the DB. Essentially, it should not load the data I'm trying to find. I've tried a bunch of things, and haven't figured it out yet. Here is my code:
#Test
public void testFindByInvalidLocABC() {
System.out.println("findByInvalidLocABC");
Storage result = StorageFacadeTest.facade.findByLoc("ABC");
assertNotNull(result);
assertEquals("NOK-0000001402", result.getId());
assertEquals("ABC", result.getLoc());
}
Any suggestions is greatly appreciated!
I have a test case I'm trying to finish. It should try to find
location ABC, but that doesn't actually exist in the DB
To ensure that data be present or not present during test executions, you cannot rely on a applicative or shared database.
Automated tests have to be repeatable. Otherwise, these will be reliable today but useless and error prone tomorrow.
So I encourage you to clean/populate a test database( or schema) before the tests be executed.
Besides, as others commented, your test doesn't look like a "not found" scenario. You assert the retrieved Storage content. It makes no sense.
It should rather look like :
#Test
public void findByLoc_with_invalidLoc_returns_null() {
Storage result = StorageFacadeTest.facade.findByLoc("ABC");
assertNull(result);
}
Some improvements for your unit test:
1) Returning Optional instead of null in the method under test is probably better but you don't use it in your actual implementation. So I follow it in my example.
2) System.out is really not advised in the test code.
3) The test prefix in the test method is not advised either. It is a legacy way as Java annotations didn't exist.

How can I avoid annotations executing before every test?

Apologies for any formatting issues or anything else against etiquette on this site, this is my first post after lurking for the last couple of months and everything that I am working with is pretty new to me.
I have recently started to write some selenium tests in Java/Cucumber/JUnit and have reached an issue that I can't work my way around. I know what the problem is but can't figure out how to actually change my tests to remedy it. Here is some of the background info:
feature file example:
Feature: Form Submission functionality
#Run
Scenario: Submitting the demo form with correct details is succesful
Given I am on the demo page
When I submit the demo form with valid information
Then the thank you page is displayed
StepDefs file example (I have four files like this, testing different parts of the site):
package testFiles.stepDefinitions;
import testFiles.testClasses.formSubmissionFunctionalityTest;
import cucumber.api.java.en.*;
import cucumber.api.java.After;
import cucumber.api.java.Before;
public class formSubmissionFunctionalityStepDefs {
private formSubmissionFunctionalityTest script = new formSubmissionFunctionalityTest();
#Before
public void setUpWebDriver() throws Exception {
script.setUp();
}
#Given("^I am on the demo page$")
public void i_am_on_the_demo_page() throws Throwable {
script.goToDemoPage();
}
#When("^I submit the demo form with valid information$")
public void i_submit_the_demo_form_with_valid_information() throws Throwable {
script.fillSubmitDemoForm();
}
#Then("^the thank you page is displayed$")
public void the_thank_you_page_is_displayed() throws Throwable {
script.checkThankYouPageTitle();
}
#After
public void tidyUp() {
script.tearDown();
}
}
I then also have a formSubmissionFunctionalityTest.java file which contains all of the actual code for methods such as fillSubmitDemoFrom. I also have a setupTest.java file with methods such as tearDown and setUp in.
The problem I am having is that every time I execute a test, four browser sessions are opened rather than the desired single browser. I know that this is because the #Before and #After annotations are executed before each test, rather than before the whole suite. I think that the best solution would be to have a new file with the #Before and #After in, but this is the part that I can't seem to figure out. In each file, script is different, which is where I think the problems come from, but I am not entirely sure.
Does anyone know of a way I can restructure my tests so that they all share the same #Before and #After methods, without causing multiple browser sessions to open? Thank you in advance
The issue isn't really the before and after, it's how you are managing your instance of WebDriver. Generally you need to maintain a single instance of it inside something like a singleton. You can do this through a classic signleton pattern, or you can do it through injection.
I highly recommend that you check out The Cucumber for Java Book. It's not going to solve all of the challenges you will face, but it is a great book for Cucumber when you are working in Java. Chapter 12 is all about using WebDriver in cucumber and talks about using injection to reuse the browser.

How do you customize exception handling behavior in JUnit 3?

I want to implement exception checking (like in JUnit 4) using JUnit 3. For example, I would like to be able to write tests like this:
public void testMyExceptionThrown() throws Exception {
shouldThrow(MyException.class);
doSomethingThatMightThrowMyException();
}
This should succeed if and only if a MyException is thrown.
There is the ExceptionTestCase class in JUnit, but but I want something that each test* method can decide to use or not use. What is the best way to achieve this?
Would the solution:
public void testMyExceptionThrown() throws Exception {
try {
doSomethingThatMightThrowMyException();
fail("Expected Exception MyException");
} catch(MyException e) {
// do nothing, it's OK
}
}
be suitable for what you're thinking of?
Also have a look at this thread, where someone created a Proxy-solution for JUnit3 which seems to be another possibility to solve your problem.
There is no need to implement your own solution because there is already one that can be used with JUnit3 (and any other testing framework): catch-exception.
The simplest approach is to use the Execute Around idiom to abstract away the try-catch that you would usually write.
More sophisticated is to note that TestCase is just a Test. I forget the details, but we can override the execution of the test (which the framework initially calls through run(TestResult) specified in Test). In that override we can place the try-catch, as per Execute Around. The testXxx method should call a set method to install the expected exception type.

Categories

Resources