How to extract Scenario outline Examples values in After hook - java

For reporting purposes I need to determine Scenario outline Examples in Cucumber (JVM6).
Looks like there is no obvious way to do it other than doing it directly in StepDefs.
Lets assume I have scenario like this:
Scenario Outline: Name
When I call cat by name "<catName>"
Then It responses
Examples:
| catName |
| Fluffy |
| Snowy |
I would like to do something like:
#After
public void report(Scenario scenario) {
List<Examples> examples = scenario.getExamples();
}
Unfortunately adding examples value extraction StepDefs is not an option. As well as adding new technical step.

Related

Feature file with scenario outline and quotes in data

I have Scenario in a feature file where i am given a message to verify with quotes. Please look in the following example:
Scenario Outline: Testing xyz
Give you are a valid user
When you log in to the System as Richard
Then you will be welcomed with "<Msg>"
Examples:
| Msg |
| Welcome to this application "Richard" |
Sample stub method for the #Then part:
#Then
public void Welcome to this application Richard(String arg){
System.out.println(arg);
}
OUTPUT:
Welcome to this application
Notice that the arg parameter does not contain word "Richard" with quotation. But business rules say the message should have the quotes around the name.
Can any one help me to write the feature file so that i get the word "Richard" in my parameter with the quotes?
I am using Java + Selenium + Cucumber

Getting "Does not have a matching glue code" error for empty fields using Cucumber

I'm new to Cucumber. I want to test two login scenarios:
With valid credentials where user should be able to login successfully
With empty username and password where the user should not be able to login
I have the following code for the above scenario:
Scenario Outline: Test login with valid credentials
Given Open firefox and start application
When I enter "<username>" and "<password>"
Then User should be able to login successfully
Examples:
| username | password |
| ro | mech |
Scenario Outline: Test login with empty credentials
Given Open firefox and start application
When I enter "<username>" and "<password>" (this shows a warning)
Then User should be not able to login
Examples:
| username | password |
| | |
In the java file I have the following code:
#When("^I enter \"([^\"]*)\" and \"([^\"]*)\"$")
public void I_enter_and_(String username, String password) throws Throwable {
driver.findElement(By.id("ember629")).sendKeys(username);
driver.findElement(By.id("ember640")).sendKeys(password);
}
My question is scenario 2 shows a warning message:
Step 'I enter "<username>" and "<password>"' does not have a matching glue code
Does this mean that for every scenario like valid, empty and invalid credentials I need to write a separate java function? Can't I use the same java function:
public void I_enter_and_(String username, String password)
for all the scenarios? If I run the feature file I get this output:
You can implement missing steps with the snippets below:
#When("^I enter \"([^\"]*)\" and \"([^\"]*)\"$")
public void i_enter_and(String arg1, String arg2) throws Throwable {
// Write code here that turns the phrase above into concrete actions
throw new PendingException();
}
Is there any way to reuse the java function I_enter_and_?
First of all, if that's an actual copy/paste of your error, it looks like you have an extra space after I enter in your step. To be sure, just copy the automatically suggested step and use it instead of the current one.
Another thing is that tat does not make sense to use Scenario Outline if you do not provide more than one example. It should look more like:
Scenario Outline: Test login with valid credentials
Given Open firefox and start application
When I enter "<username>" and "<password>"
Then User "<maybe>" be able to login successfully
Examples:
| username | password | maybe |
| ro | mech | shall |
| | | shall not |
Glue path would be correct and match with stepdef path as follows:

Execute only specific examples in a Scenario Outline

We're looking to better manage test data using Cucumber in our Java test automation framework. For a Scenario Outline, we're looking to tabulate test parameters categorized by the applicable environment in which they will run.
For example,
Scenario Outline: Login into application
Given I am on the homepage in the <environment>
When I enter my <user>
And I enter my <pass>
Then I am taken to the homepage
Examples:
|user |pass |environment|
|test |test1 |local |
|retest |retest1 |sit |
|prodtest|prodtest1|production |
So, when the above scenario is executing in, for example, the SIT environment, only the 2nd example will be picked up, and not the first and third.
Can this level of execution be accomplished?
You can get this done by splitting up your examples table into two and using tags on them... Then run the test with the tags to filter in cucumberoptions.
#others
Examples:
|user |pass |environment|
|test |test1 |local |
|prodtest|prodtest1|production |
#sit
Examples:
|user |pass |environment|
|retest |retest1 |sit |
That is not what scenario outlines are designed for.
You can write separate scenario's and then use tags on each one that you can then pass in at runtime which tag you want to run.

Spock - returning fixed value not working as expected

I have to begin by apologising if the terms I use are incorrect. I use groovy/java for automation tasks only(Gradle), and I don't have years of experience delivering production grade software.
So, the challenge that I have is as follows: I have a spec which is trying to test a return string is as expected (almost identical to this).
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Stub()
stubCert.getSubjectDN().toString() >> "Test"
when:
def output = X509CertificateUtils.prettyPrint(stubCert)
then:
output == "Subject: Test"
}
However, the difference is that my method constraint returns a Principal object, and its that object's toString() that I really want to stub. I thought I was doing that correctly above, but it doesn't give the result I expect.
Here's my helper class.
import java.security.cert.X509Certificate
class X509CertificateUtils {
static def prettyPrint(X509Certificate x509Certificate) {
return "Subject: ${x509Certificate.getSubjectDN()}"
}
}
If I run this test I get the following error:
output == "Subject: Test"
| |
| false
| 38 differences (20% similarity)
| Subject: (Mock for )t(ype 'Principal' named 'dummy')
| Subject: (Tes------)t(-----------------------------)
Subject: Mock for type 'Principal' named 'dummy'
Any help would be gratefully received.
Just create a second stub:
X509Certificate stubCert = Stub()
Principal princ = Stub()
princ.toString() >> "Test"
stubCert.getSubjectDN() >> princ
Spock has a few approaches to faking objects. Here's the current documentation.
Stub: A fake object that returns only what it is told to; a default
value otherwise (0, Empty, etc).
Mock: Similar to a stub, but it
can also test the number of method calls made on the object.
Spy: A normal instantiation of your object, the mocks are applied as listeners that intercept calls to the object. This lets you use the object normally, with only the specified methods behaviors changing. It's also possible to call the original code at some point during your mocked behavior.
My question for you... Are you attempting to test that prettyPrint() alone is working properly, that SubjectDN.toString() prints properly, or a combination of the two? My suggestion is to have your mock return an actual SubjectDN() object that you then test as well. Not much more work, and if something breaks you have a better idea of where the problem originated. Max's solution will solve your question; I didn't read close enough or follow good test scoping practices. I'll leave the rest of my answer as food for thought. If you want to mix Max's stub approach with my parameterization I would suggest passing the desired string in the where block to the stub creation in the setup block.
This is beginning to get off topic, but if you need to test more than one SubjectDN scenario (null, empty, various capitalizations, numerics, etc); you should look into parameterizing your test as well.
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> subject
expect:
subject.toString() == expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
subject | expectedToString | expectedFormatted
new SubjectDN("") | ???? | "Subject: ????"
new SubjectDN(null) | ???? | "Subject: ????"
new SubjectDN("test") | "test" | "Subject: Test"
new SubjectDN("testing") | "testing" | "Subject: Testing"
}
If your pretty printing really is as simple as prepending "Subject: " you could probably get away with computing your expectedFormatted variable; but you really shouldn't have your test mimic the code you're testing in an attempt to make testing easier.
I also find that the table format of parameterizing the tests gets messy or difficult to maintain when the the iterations have a fluid length. My preference is to make a list of maps, with each map representing a test iteration. It keeps each test iteration bundled together and gives unfamiliar developers a better idea of what each iteration of the test entails.
#Unroll(iteration.testName) // Shows each iteration in its own result (in most IDEs)
def "testing printing of a SubjectDN"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> iteration.subject
expect:
subject.toString() == iteration.expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
iteration << [
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("test"),
expectedToString: "test"],
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("testing 123"),
expectedToString: "testing 123"],
[testName: "Testing pretty printing a null SubjectDN",
subject: new SubjectDN(null),
expectedToString: ????]
// And so on...
]
expectedFormatted = "Subject: ${iteration.expectedToString}"
}

how to run junit tests on a examples file

I have a method under test which gets as input 2 strings and returns a double.
Instead of writing a separate UT for each of them like this:
public void test1() throws Exception {
double answer = nameSimilarity.similarity("aaaa", "abbba");
assertThat(answer, greaterThan(THRESHHOLD));
}
I want to write a write an input batch file like this:
string1 - string 2 - expect result to be greater than THRESHHOLD
aaaa - abbba - True
cccc - abbba - True
cccc - zzzzz - False
how do you suggest I'll read the file, parse it and run a unit test on each row?
Is there any built in such functionality in junit with any convention ?
You can take a look behaviour driven development cucumber, which can support such kind of testing sample data called "Data Tables".
For example:
Scenario Outline: Email confirmation
Given I have a user account with my name "Jojo Binks"
When an Admin grants me <Role> rights
Then I should receive an email with the body:
"""
Dear Jojo Binks,
You have been granted <Role> rights. You are <details>. Please be responsible.
-The Admins
"""
Examples:
| Role | details |
| Manager | now able to manage your employee accounts |
| Admin | able to manage any user account on the system |
there is no such functionality in junit. also, in Junit you normally run each test case separately and give each a different name. Junit discourages running many tests in the same test case (it will fail if only one out of 20 tests succeed or 19 of them fail).
Your test case should have the general structure of:
public void testTooManyCases() {
while get a line and !eof // catch exceptions and in finally close the file
parse the line
//e.g: String[] parts = line.split(","); //use comma to separate in the input file
//calculate the answer for the info in the line
//e.g: double answer = nameSimilarity.similarity(parts[0], parts[1]);
//assert
//e.g.: assertTrue((answer > THRESHHOLD) == new Boolean(parts[2]).booleanValue());
}
your file should have in each line something like:
aaaa,abbba,true
cccc,zzzzz,false

Categories