Specflow - How to pass on the data which has brackets to the step definition without any data loss - bdd

I have a specflow test which looks like this
When I create a team with <TeamName> <MemberName> <MemberMobileNumber> successfully
Examples:
|TeamName|MemberName|MemberMobileNumber|
|Apple(RD) |James(Smith)|(09)1234567|
If you observe, we have brackets in the test data details and when I read the data, the data is distorted. Is there a way to write the step definition in such a way that the data is not distorted.
The step definition looks like this
[When(#"I create a team with (.*) (.*) (.*) successfully")]
public void WhenICreateATeamWithTeam......{
}
Thanks a lot for your help on this.

Don't see any data loses in your example:
I also tried with Table and it works well.
I got data loses when I tried to make steps like this:
[When(#"I create a team with \(.*) \(.*) \(.*)")]
My version of SpecFlow is 2.4.0

For given specification in .feature file as you showed in question:
Scenario Outline: workWork
When I create a team with <TeamName> <MemberName> <MemberMobileNumber> successfully
Examples:
|TeamName |MemberName |MemberMobileNumber |
|Apple(RD) |James(Smith) |(09)1234567 |
And for step definition like:
[When(#"I create a team with (.*) (.*) (.*) successfully")]
public void WhenICreateATeamWithAppleRDJamesSmithSuccessfully(string p0, string p1, string p2)
{
}
Then data inside p0, p1 and p2 parameters in step is as expected: p0 = "Apple(RD)", p1 = "James(Smith)", p3 = "(09)1234567".
There is 2nd way to do this, using "" for textual data in .feature file, and then follow that with ""(.*)"" in regular expression (in method generated in step.cs file) for every input parameter.
Scenario Outline: workWork
When I create a team with <TeamName> <MemberName> <MemberMobileNumber> successfully
Examples:
|TeamName |MemberName |MemberMobileNumber |
|"Apple(RD)" |"James(Smith)" |"(09)1234567" |
[When(#"I create a team with ""(.*)"" ""(.*)"" ""(.*)"" successfully")]
public void WhenICreateATeamWithAppleRDJamesSmithSuccessfully(string p0, string p1, string p2)
{
}

Related

Using MySQL as input source and writing into Google BigQuery

I have an Apache Beam task that reads from a MySQL source using JDBC and it's supposed to write the data as it is to a BigQuery table. No transformation is performed at this point, that will come later on, for the moment I just want the database output to be directly written into BigQuery.
This is the main method trying to perform this operation:
public static void main(String[] args) {
Options options = PipelineOptionsFactory.fromArgs(args).withValidation().as(Options.class);
Pipeline p = Pipeline.create(options);
// Build the table schema for the output table.
List<TableFieldSchema> fields = new ArrayList<>();
fields.add(new TableFieldSchema().setName("phone").setType("STRING"));
fields.add(new TableFieldSchema().setName("url").setType("STRING"));
TableSchema schema = new TableSchema().setFields(fields);
p.apply(JdbcIO.<KV<String, String>>read()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create(
"com.mysql.jdbc.Driver", "jdbc:mysql://host:3306/db_name")
.withUsername("user")
.withPassword("pass"))
.withQuery("SELECT phone_number, identity_profile_image FROM scraper_caller_identities LIMIT 100")
.withRowMapper(new JdbcIO.RowMapper<KV<String, String>>() {
public KV<String, String> mapRow(ResultSet resultSet) throws Exception {
return KV.of(resultSet.getString(1), resultSet.getString(2));
}
})
.apply(BigQueryIO.Write
.to(options.getOutput())
.withSchema(schema)
.withCreateDisposition(BigQueryIO.Write.CreateDisposition.CREATE_IF_NEEDED)
.withWriteDisposition(BigQueryIO.Write.WriteDisposition.WRITE_TRUNCATE)));
p.run();
}
But when I execute the template using maven, I get the following error:
Test.java:[184,6] cannot find symbol symbol: method
apply(com.google.cloud.dataflow.sdk.io.BigQueryIO.Write.Bound)
location: class org.apache.beam.sdk.io.jdbc.JdbcIO.Read<com.google.cloud.dataflow.sdk.values.KV<java.lang.String,java.lang.String>>
It seems that I'm not passing BigQueryIO.Write the expected data collection and that's what I am struggling with at the moment.
How can I make the data coming from MySQL meets BigQuery's expectations in this case?
I think that you need to provide a PCollection<TableRow> to BigQueryIO.Write instead of the PCollection<KV<String,String>> type that the RowMapper is outputting.
Also, please use the correct column name and value pairs when setting the TableRow.
Note: I think that your KVs are the phone and url values (e.g. {"555-555-1234": "http://www.url.com"}), not the column name and value pairs (e.g. {"phone": "555-555-1234", "url": "http://www.url.com"})
See the example here:
https://beam.apache.org/documentation/sdks/javadoc/0.5.0/
Would you please give this a try and let me know if it works for you? Hope this helps.

Is it possible to use parameterised test case data with Xcode's XCTest Framework?

Something similar to the TestCaseAttribute that NUnit has, along the lines of:
[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual( q, n / d );
}
Is it possible to provide parameterised test case data like this, in Xcode?
It does not look like XCTest has this built in, but there is project on GitHub aims to add this functionaltiy.
From their ReadMe:
KNMParametrizedTest adds support for parametrized test cases using the XCTest framework. Here is an example:
KNMParametersFor(testExample, #[ #"Hello", #"World" ])
- (void)testExample:(NSString *)word
{
NSString *result = [myUppercaser uppercaseString:word];
XCTAssertEqualObjects(result, [word uppercaseString],
#"Uppercaser failed for word %#", word);
}
It looks like the easiest way to install this is through CocoaPods.
Although XCTest doesn't offer a proper means of writing parameterized tests, I found a nice, simple workaround in page 46 of Godfrey Nolan's book Agile Swift which is to define an array of tuples containing the input and output values, and then to iterate through each item in the array, as follows:
func test_multiple() {
let cases = [(4,3,12),(2,4,8)]
cases.forEach {
XCTAssertEqual(myCalculator.multiply($0, $1), $2)
}
}
The only caveat with this approach that I can see is that you'll only get one entry in the test navigator / test report rather than one for each test case. But the time you'll save from not having to write the same test again and again (with only a slight variation in each test) is well worth it in my opinion.
If you want a nice message in the case of a failed test, you can easily get this by adding one more element to the tuple which represents the message to pass into the XCTAssertEqual call, as follows:
func test_multiple() {
let cases = [(4,3,12,"4 times 3"),(2,4,8,"2 times 4")]
cases.forEach {
XCTAssertEqual(myCalculator.multiply($0, $1), $2, $3)
}
}

How to write fitnesse code for a method which accepts 2 parameters

I'm newbie to fitnesse and trying to run a simple calculator class which has "add" method accepting 2 parameters and returning the result. Can anyone help me to write the firnesse code for this, my method is as below
public int add(int a, int b) {
return a+b;
}
I believe you are trying to get a table like:
|AddFixtureTest |
|left|right|sum?|
|1 |1 |2 |
|2 |4 |6 |
This requires a java class like:
import fit.ColumnFixture;
public class AddFixtureTest extends ColumnFixture {
public int left;
public int right;
public int sum(){
return add(left, right);
}
private int add(int a, int b) {
return a+b;
}
}
See http://fitnesse.org/FitNesse.UserGuide.FixtureGallery.BasicFitFixtures.ColumnFixture
I assume Slim is fine by you and I'm gonna use script table for this (more out of habit):
|script| <class name> |
|add;| <variable1> | <variable2> |
As simple as that. And, make sure you are using the right libraries and pointing to the location of the where the class file is.
Example:
|import|
fitnesse.slim.test |
If you are interested in knowing why I have placed a semi-colon after "add", and how script table works, please go through this:
http://www.fitnesse.org/FitNesse.UserGuide.WritingAcceptanceTests.SliM.ScriptTable
You can get the FitNesse tutorial there for .Net code. I tried to describe how to use FitNesse for different types of testing.
If you want to check two parameters on the output you can do the following:
Return IEnumerable implementation with classes, which contains get
and set properties (see here). NetRunner will use get properties
if it can, otherwise it will use set properties. As a result, it will
set all available data first and then compare items left.
You can use out parameters in the tests, so you can return several different values and check them
The correct answer is:
|script:<classPackage>.<ClassName>|
|check|add;|8|8|16|
First tell the script to navigate to the correct class. In the next line you have to call either a method or a constructor. You can call the method by it's name (or fancy smansy digibetic words that vaguely match) and tack on a semicolon. But anything put into the pipe-blocks after that will be interpreted as parameters for that method. So how do you put the expected output?
The trick is to tell the FitNesse engine you need a result, with the keyword 'check'.
This will make the final pipe-block be the field for the expected result, in this case 16.
Here is a picture of the java code
Here is a picture of the text input and the FitNesse sceen result

Specflow ignores When step in F# step assembly

I am using VS2010, SpecFlow 1.9.0, NUnit 2.6.2 and ReSharper 7.1. I have a feature file taken from the example:
Feature: SpecFlowFeature1
In order to avoid silly mistakes
As a math idiot
I want to be told the sum of two numbers
#mytag
Scenario: Add two numbers
Given I have entered 50 into the calculator
And I have entered 70 into the calculator
When I press the add button
Then the result should be 120 on the screen
I have implemented the step definitions in a separate F# assembly:
[<TechTalk.SpecFlow.Binding>]
module StepDefinitions
open TechTalk.SpecFlow
open NUnit.Framework
let [<Given>] ``I have entered (.*) into the calculator`` (a: int) =
ScenarioContext.Current.Pending()
let [<When>] ``I press the add button`` =
ScenarioContext.Current.Pending()
let [<Then>] ``the result should be (.*) on the screen`` (r: int) =
ScenarioContext.Current.Pending()
I have told SpecFlow where to find them via the stepAssemblies tag in app.config
However, when I run the test, it finds the Given and Then steps, but not the When step. The error I get is:
No matching step definition found for one or more steps.
using System;
using TechTalk.SpecFlow;
namespace MyNamespace
{
[Binding]
public class StepDefinitions
{
[When(#"I press the add button")]
public void WhenIPressTheAddButton()
{
ScenarioContext.Current.Pending();
}
}
}
Given I have entered 50 into the calculator
-> pending: StepDefinitions.I have entered (.*) into the calculator(50)
And I have entered 70 into the calculator
-> skipped because of previous errors
When I press the add button
-> No matching step definition found for the step. Use the following code to create one:
[When(#"I press the add button")]
public void WhenIPressTheAddButton()
{
ScenarioContext.Current.Pending();
}
Then the result should be 120 on the screen
-> skipped because of previous errors
Have I gone wrong somewhere, or is there a bug with F# support?
The correct translation of the C# is actually
let [<When>] ``I press the add button``() =
ScenarioContext.Current.Pending()
Note the extra (). As this was missing in the original version, the function had a different signature which meant that it wasn't found.

MbUnit's row attribute in NUnit?

While reading an Asp.Net MVC code sample that used MbUnit as it's testing framework, I saw that it was possible to run a single test against multiple input possibilities by using a Row attribute, like so:
[Test]
[Row("test#test_test.com")]
[Row("sdfdf dsfsdf")]
[Row("sdfdf#.com")]
public void Invalid_Emails_Should_Return_False(string invalidEmail)
{
...
}
Please I'd like to know if there is an NUnit equivalent of MbUnit's Row attribute , or otherwise an elegant way to achieve this in NUnit. Thanks.
I think you're after the TestCase attribute
[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
Assert.AreEqual( q, n / d );
}
http://www.nunit.com/index.php?p=testCase&r=2.5.7
NUnits Sequential attribute does exactly that.
The SequentialAttribute is used on a
test to specify that NUnit should
generate test cases by selecting
individual data items provided for the
parameters of the test, without
generating additional combinations.
Note: If parameter data is provided by
multiple attributes, the order in
which NUnit uses the data items is not
guaranteed. However, it can be
expected to remain constant for a
given runtime and operating system.
Example The following test will be
executed three times, as follows:
MyTest(1, "A")
MyTest(2, "B")
MyTest(3, null)
[Test, Sequential]
public void MyTest(
[Values(1,2,3)] int x,
[Values("A","B")] string s)
{
...
}
Given your example, this would become
[Test, Sequential]
public void IsValidEmail_Invalid_Emails_Should_Return_False(
[Values("test#test_test.com"
, "sdfdf dsfsdf"
, "sdfdf#.com")] string invalidEmail)
{
...
}

Resources