How to use result returned from before or background scenarios in cucumber java testing? - cucumber-jvm

I have two scenarios named "X" and "Y" ( many others)
Before testing scenario "Y", I need to run Scenario "X" and return the results from scenario "X" to scenario "Y". How should I do that ?
I have tried 2 options
1: I have created background scenario for X but I am not able to return result from that background scenario X to scenario Y.
2: I have also tried using before hook up annotation.
(PS: I know while testing all test-cases should be independent of each other)

Perhaps the simplest way is to place both steps in the same class then use class instance variables.
public class SomeSteps {
private List<String> betweenStepsList;
#When("^I initialize a list in one step$")
public void iInitializeAListInOneStep() {
betweenStepsList = new ArrayList<String>(Arrays.asList("Peter","Piper","picked","a","peck","of","pickled","peppers"));
}
#Then("^I can access that list in a following step$")
public void iCanAccessThatListInAFollowingStep() {
System.out.println("Elements are:" + betweenStepsList);
}
}
EDIT
You did say two scenarios. When I face this issue I always find a way to combine the scenarios into one.
You could write the intermediate results to a file in the first scenario and then read them in the second. I never bother to do this myself but there are lots of tutorials on how to read and write files. Here is one for Java. Ruby or Python (you didn't specify) examples for writing then reading a file are also easily available.
Parallel execution is fine as long as both scenarios are in the same feature file.

Related

What is the proper way to extend a Fixture with a Parameter Interface and add new parameters of a different type?

Let's assume I have a test fixture that inherits from ::testing::WithParamInterface<MyType> that uses it in SetUp().
class MyFixture : ..., ::testing::test, ::testing::WithParamInterface<MyType> {
virtual void SetUp() override {
auto param = GetParam();
...
}
};
I wish to write a text fixture that subclasses this, however will provide a param interface in addition to the one the current fixture provides. i.e. something like:
class SubclassedFixture : ..., MyFixture, ::testing::WithParamInterface<MySecondType> { ... };
Ideally this would then run all tests in MyFixture with the types specified in INSTANTIATE_TEST_CASE_P(..., MyFixture, {MyFixtureSpecifiedValues}). And then run all the tests in SubclassedFixture over the combinations INSTANTIATE_TEST_CASE_P(..., SubclassedFixture, {MyFixtureSpecifiedValues} x {SubclassedFixtureValues}).
A secondary goal here is to change as little code as possible in the already existing MyFixture class.
I do not expect anything in Google Test to neatly support this. However what would be the best way to restructure these tests to get this functionality, changing MyFixture at little as possible?

add completionitemprovider and keep suggestions

I created a completionitemprovider for my extension, but now the suggestions based on words in the document aren't shown. Do I have to provide each word in the document?
export class ScriptViewProvider implements vscode.CompletionItemProvider
...
extension.context.subscriptions.push(vscode.languages.registerCompletionItemProvider(
["language"],
this));
...
async provideCompletionItems(document : vscode.TextDocument, position : vscode.Position) : Promise<vscode.CompletionItem[]> {
let completions : vscode.CompletionItem[] = [];
let completion = new vscode.CompletionItem("bla", vscode.CompletionItemKind.Field);
completions.push(completion);
return completions;
}
It brings up "bla" when I type "b", but none of the other words in the document appear.
See this comment of an open VS Code issue.
When your CompletionProvider was registered using a DocumentSelector that is more significant than that of other providers and returns at least one completion item, the other providers are skipped.
The word-based suggestions provider is less significant and so it does not contribute any suggestions.
Depending on the nature of your extension you could try to define a less specific DocumentSelector when registering your CompletionProvider.
If this is not possible I think there is no other option than to providing all completion items yourself (including word-based suggestions).

Want to use one tag with different values according to the scenario in cucumber

we have a cleanup hook in our automation framework which tagged from the cucumber feature file
E.g
#cc_task_clean_up_hook_enrol_A
Scenario: Person can enrol_A
When I select the context menu
Then I am able to enroll the patient into 'enrol_A'
the implementation of the hook (#cc_task_clean_up_hook) is
#After(value = "#toc_task_clean_up_hook_enrol_A", order = HookOrder.CLEAN_UP_APP_AFTER)
public void cleanUpTOC() {
this.patientContextPage.selectedContextMenuItem("Pathway");
this.pathWayPage.selectReferences("Enroll in Pathway");
this.pathWayPage.deactivateEnrollment("enrol_A", "Withdrawn");
}
So exactly the same way we need an another scenario like
Scenario: Person can enroll_B
When I select the context menu
Then I am able to enroll the patient into 'enrollB'
So we can implement another hook as follows, the difference is the parameter type "enrollB"
#After(value = "#toc_task_clean_up_hook_enrollB", order = HookOrder.CLEAN_UP_APP_AFTER)
public void cleanUpTOC() {
this.patientContextPage.selectedContextMenuItem("Pathway");
this.pathWayPage.selectReferences("Enroll in Pathway");
this.pathWayPage.deactivateEnrollment("enrol_B", "Withdrawn");
}
So is it possible to consolidate these two methods and write only one generic clean up hook, based on the passed parameter? Your help is much appreciated.
You can add the scenario object to the arguments passed to the after hook. The framework will inject the currently executing scenario to the method.
public void afterMethod(Scenario scenario){}
You can use the getSourceTagNames() method of the Scenario object which will return you the collection of tags for the current executing scenario. From this collection you can determine if you have the tag ending with 'enroll_A' or 'enroll_B'.
Or you can use the getName() method which returns the description of the current scenario. So you will get either 'Person can enroll_A' or 'P..... enroll_B'. Just need to parse again.
You can modify the Then step to pass the enroll type to step definition. Store this in a variable. Use this variable in your after hook. But this will require the after hook to be in the same class.
Also you will need to change the value parameter of After hook to - {"#toc_task_clean_up_hook_enrollA,#toc_task_clean_up_hook_enrollB"}.
One observation that these two seem to have the same steps, if so then have you considered ScenarioOutline instead.

I want to automate a scenario in which multiple products needs to be asserted with respect to filter values from a ecommerce website?

I want to automate a scenario in which multiple products needs to be asserted with respect to filter values from a ecommerce website. I want to know what could be the approach which we can implement using selenium?
hi plz try like below
public class ComparingItems {
public static void main(String[] args) {
// Multiple products
String mProducts[] = {"Reebok","addidas","puma"};
// filter values from e commerce website
String eProducts[] = {"Reebok","Fila","puma"};
// now how to assert the two use below logic
for(int i=0;i< mProducts.length;i++){
Assert.assertEquals(mProducts[i], eProducts[i], "Item Not matched");
}
}
}
**RegressionTestSuite**
#test
1)filter1
#test
2)filter2
#test
3)filter3
#test
4)filter1 and filter2
#test
5)filter1 and filter3
#test
6)filter2 and filter3
*CommonOperations class* //abstract class
void selectCategories(String variable){}
void setFilterCriteria(filter1, filter2, filter3){}
void hoverProduct(){}
void clickAndViewDetails() {}
// there could be many more methods which are common to finding product details across the website.
FilterTypeMobile interface
{void getMobileDetails(){}
filter variable common to mobile phones
}
class TelevisionProduct implements FilterTypeTelevision
{#overridden
void getTelevisionDetails(){}
}
FilterTypeTelevision interface
{void getTelevisionDetails(){}
filter variable common to Televisions
}
class MobileProduct implements FilterTypeMobile
{#overridden
void getMobileDetails(){}
}
I have basically written basic framework without impplementation. Right now I am just deciding on the strategy to achieve automation.
You can develop a framework for same, here are a few best practices which I follow:
Make good use of Test Execution frameworks. I use TestNG.
I create a base file which makes use of most of the TestNG annotations for Setting and Tearing up.
Separate your Re-usable functions and call it wherever needed. I generally add these in the base class.
I personally prefer keeping locators too in the base file if they are too complicated. This would help you to change the locator from one place and get reflected for all. In this case, do follow a good naming convention.
Use collections wherever possible.
You can use something like ReportNG for more user friendly reports.
Make more use of implicit waits and avoid using JavascriptExecutors.
Copy the Drivers and libraries within the project folders for better mobility and less external dependencies.
Adding selenium WD javadoc to your project will be of some help.
We also make sure we have a screenshot for failed test case by over-riding the onTestFailure method.
Rest all are simple coding basics for cleaner and easy to understand code that I believe you'll be following anyway.
Also, this may not be the best place to post such query as per regulations of this forum. But still I believe my answer is of some help.

NHibernate testing, mocking ISession

I am using NHibernate and Rhinomocks and having trouble testing what I want. I would like to test the following repository method without hitting the database (where _session is injected into the repository as ISession):
public class Repository : IRepository
{
(... code snipped for brevity ...)
public T FindBy<T>(Expression<Func<T, bool>> where)
{
return _session.Linq<T>().Where(where).FirstOrDefault();
}
}
My initial approach is to mock ISession, and return an IQueryable stub (hand coded) when Linq is called. I have a IList of Customer objects I would like to query in memeory to test my Linq query code without hitting the db. And I'm not sure what this would look like. Do I write my own implementation of IQueryable? If so, has someone done this for this approach? Or do I need to look at other avenues?
Thanks!
How I've done this test is to not pass the expression to the repository, instead expose IQueryable giving the repository an interface such as:
public interface IRepository<T>
{
IQueryable<T> All();
// whatever else you want
}
Easily implemented like so:
public IQueryable<T> All()
{
return session.Linq<T>();
}
This means that instead of calling your method on the repository like:
var result = repository.FindBy(x => x.Id == 1);
You can do:
var result = repository.All().Where(x => x.Id == 1);
Or the LINQ syntax:
var result = from instance in repository.All()
where instance.Id == 1
select instance;
This then means you can get the same test by mocking the repository out directly which should be easier. You just get the mock to return a list you have created and called AsQueryable() on.
As you have pointed out, the point of this is to let you test the logic of your queries without involving the database which would slow them down dramatically.
From my point of view is this would be considered Integration Testing. NHibernate has it's own tests that it passes and it seems to me like you're trying duplicate some of those tests in your own test suite. I'd either add the NHibernate code and tests to your project and add this there along with their tests, thats if they don't have one very similiar, and use their methods of testing or move this to an Integration testing scenario and hit the database.
If it's just the fact you don't want to have to setup a database to test against you're in luck since you're using NHibernate. With some googling you can find quite a few examples of how to use SQLite to "kinda" do integration testing with the database but keep it in memory.