Do we have any annotation in cucumber where it will run before any of the tests in the feature file? - cucumber

#Before method will run before every scenario. Do we have an annotation where it run before any of the scenarion and an annotation after all the scenarios have been executed ?

You can use gerkin with qaf where you can use different TestNG listeners and annotations. In addition to that if you are using webdriver you can get additional driver and element listeners support. For example
package my.test.pkg
public class MyClass{
#BeforeSuite
public void beforeSuite() {
//get executed before suite
}
#BeforeTest
public void beforeTest() {
//get executed before each xml test
}
#BeforeMethod
public void beforeMethod() {
//get executed before each test case/scenario
}
#BeforeGroups(["p1","p2"])
public void beforeMethod() {
//get executed before group
}
//same for after methods #afterXXXXX
}
You need to add class in config file:
<test name="Gherkin-QAF-Test">
<classes>
<class name="com.qmetry.qaf.automation.step.client.gherkin.GherkinScenarioFactory" />
<class name="my.test.pkg.Myclass" />
</classes>
</test>
This example is not using listeners. You also can use different listeners.

As pointed in comments cucumber does not have an out-of-box solution for this.
But you can create a before hook to run once only using a static flag.
private static boolean skipFlag = false;
#Before
public void beforeHook() {
if(!skipFlag) {
do stuff
skipFlag=true;
}
}
Modify the Before hook to run for certain tags etc..
The after hook to run at the end is difficult. Either specifically create a scenario or a final step at the end in which does all the after hook stuff. Or you can write the code in a JVM shutdown hook, though it will run after all feature files are run.

Related

Issue using #Transactional annotation above integration test class for multithreading environment

When I run the integration test for code which calls JPA repository within a new thread, I'm getting data that was populated during starting PostgreSQLContainer and I can't receive data from the script above class test( #Sql(scripts ="data.sql").
But when I remove #Transactional annotation above the test I can get data both from SQL script from test and test container.
My question is it possible to get data in a multithreading environment from test script without removing #Transactional annotation?
Thank you for your answer!
Application stack: Spring boot 2.1v+ test containers PostgreSQL 1.10.3v+ JUnit 4.12v
DB testcontainers config
#TestConfiguration
public class DatabaseTestConfig {
private static JdbcDatabaseContainer PSQL;
static {
PSQL = (PostgreSQLContainer) new PostgreSQLContainer("mdillon/postgis:9.4").withUsername("test")
.withPassword("test")
.withDatabaseName("test");
PSQL.start();
Arrays.asList("main_data.sql")
.forEach(DatabaseTestConfig::restoreDump);
/*
set db properties
*/
}
public void restoreDump(String fileName){
/*
insert sql data
PSQL.copyFileToContainer(fileName)...
*/
}
}
Base Integration Test class
#RunWith(SpringRunner.class)
#SpringBootTest(classes = { DatabaseTestConfig.class, ProjectApplication.class })
#ActiveProfiles("test-int")
#AutoConfigureMockMvc
#Sql(scripts = "classpath:extra_data.sql") // insert some extra data for all integration tests
public abstract class AbstractIntTest {
#Autowired
protected MockMvc mockMvc;
Integration Test that calls service where everething happenes
#Transactional
public class SomeIntegrationTest extends AbstractIntTest {
#Before
public void setUp() throws IOException {
//...
}
#Test
public void callServiceTest() throws Exception {
//mockMvc.perform(post(ENDPOINT_URL)
}
Service with simplified logic
#Service
#AllArgsConstructor
public class SomeService {
private final SomeJpaReporistory repo;
private final ExecutorService executor;
#Override
#Transactional
public SomeData call(){
return CompletableFuture.supplyAsync(() -> {
return repo.findAll();
}, executor).exceptionally(e -> {
throw new BadRequestException(e.getMessage());
});
}
When you make the test transactional, the SQL queries in extra_data.sql are performed in a transaction. That transaction is bound to a particular thread and is begun before execution of the test method and rolled back after the test method has completed:
Begin transaction
Execute extra_data.sql
Invoke test method
Roll back transaction
In step 3 you are calling repo.findAll() on a separate thread due to your service's use of supplyAsync. As a transaction is bound to a particular thread, this findAll() call is not part of the transaction in which extra_data.sql was executed. To be able to read the data added by extra_data.sql, it would have to be able to read uncommitted changes and perform a dirty read. Postgres does not support the read uncommitted isolation level so this isn't possible.
You'll need to revisit how you're populating your database with test data or your use of transactions in your tests. Perhaps you could apply extra_data.sql to the database in the same manner as main_data.sql so that it's always in place before any tests are executed and before any transactions are begun.
This is how I've solved this problem:
#Test
#Transactional
#Sql(scripts = "/db/extra_data.sql",
config = #SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED))
void test() {
// extra_data.sql are executed before this test is run.
}

#Activate not called when starting component

Following Liferay's documentation about making modules configurable, I wrote this Liferay 7 module:
#Component(configurationPid = "myproject.api.TranslationConfiguration")
public class TranslationServiceImpl implements TranslationService {
private volatile TranslationConfiguration configuration;
public TranslationServiceImpl() {
log.info("TranslationServiceImpl constructor");
}
#Activate
#Modified
protected void activate(Map<String, Object> properties) {
log.info("Hello from activate");
}
}
When I deploy, the log only shows:
TranslationServiceImpl constructor
Service registered.
STARTED myproject.impl_1.0.0 [538]
Why is the activate method not called?
Restarting the module in Gogo Shell does not call activate either.
By default a component in declarative services is only activated when its service is referred by another bundle.
If you want it to start right away use immediate=true

How to use Class Initialize so that application opens in beginning,run all the tests & closes in the end

My code:
This is initialize method
[TestInitialize()]
public void MyTest Initialize()
{}
This is test 1
[TestMethod]
public void Validate_Create_Command()
{ }
This is test 2
[TestMethod]
public void Validate_Delete_Command()
{}
Right Now test1 opens application & closes the application &
test2 also opens the application & closes.
My question is how to open application once & close application after all tests completes
First I would recommend you always open at the beginning of the test and close at the end. Your recordings should be flexible enough that you can combine them to navigate to different parts of the app. I'll answer how best to do that in a moment first your actual question.
If you want to open at the start and close at the end I use this pattern
[TestClass]
public class Tests
{
[TestMethod]
public void TestMethod1()
{
UIMap.ClickNext();
UIMap.ClickPlusButton();
UIMap.AssertStuff();
}
[TestMethod]
public void TestMethod2()
{
UIMap.ClickNext();
UIMap.ClickMinusButton();
UIMap.AssertStuff();
}
[ClassInitialize()]
public static void ClassInitialize(TestContext testcontext)
{
Utilities.Launch();
}
[ClassCleanup()]
public static void ClassCleanup()
{
Utilities.Close();
}
}
public static class Utilities
{
private static ApplicationUnderTest App;
public static Launch()
{
try
{
App = ApplicationUnderTest.Launch(pathToExe);
}
catch (Microsoft.VisualStudio.TestTools.UITest.Extension.FailedToLaunchApplicationException e) {}
}
public static Close()
{
App.Close();
App = null;
}
}
To do this on a test to test basis you simple use the normal (below)
[TestInitialize()] and [TestCleanup()]
You could copy the method calls to launch and close the application from the test methods into the initialize and cleanup methods, then delete the calls from the test methods.
The way that Coded UI managed applications between test cases changed between Visual Studio 2010 and 2012, also the way that CloseOnPlaybackCleanup worked. For more details see http://blogs.msdn.com/b/visualstudioalm/archive/2012/11/08/using-same-applicationundertest-browserwindow-across-multiple-tests.aspx
You will need to re-record test 1 and test 2 to no longer open/close the application.
In TestInitialize, record the launching of your application.
In TestCleanup, record the closing of your application.
What will happen when you run the CodedUI test is:
Step 1: TestInitialize runs which launches your application
Step 2: Test1 and Test2 run (again, you will have removed
launching/closing of your app)
Step 3: TestCleanup runs which closes your application
#region Additional test attributes
//Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
this.UIMap.OpenMyApplication();
}
//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
this.UIMap.CloseMyApplication();
}
#endregion

BeforeFeature/AfterFeature does not work using SpecFlow and Coded UI

I am not able to define a [BeforeFeature]/[AfterFeature] hook for my feature file. The application under test is WPF standalone desktop applications.
If I use [BeforeScenario]/[AfterScenario] everything works fine, the application starts without any problem, the designed steps are performed correctly and the app is closed.
Once I use the same steps with [BeforeFeature]/[AfterFeature] tags the application starts and the test fails with:
The following error occurred when this process was started: Object reference not set to an instance of an object.
Here is an example:
[Binding]
public class Setup
{
[BeforeScenario("setup_scenario")]
public static void BeforeAppScenario()
{
UILoader.General.StartApplication();
}
[AfterScenario("setup_scenario")]
public static void AfterAppScenario()
{
UILoader.General.CloseApplication();
}
[BeforeFeature("setup_feature")]
public static void BeforeAppFeature()
{
UILoader.General.StartApplication();
}
[AfterFeature("setup_feature")]
public static void AfterAppFeature()
{
UILoader.General.CloseApplication();
}
}
StartApplication/CloseApplication were recorded and auto-generated with Coded UI Test Builder:
public void StartApplication()
{
// Launch '%ProgramFiles%\...
ApplicationUnderTest Application = ApplicationUnderTest.Launch(this.StartApplicationParams.ExePath, this.StartApplicationParams.AlternateExePath);
}
public class StartApplicationParams
{
public string ExePath = "C:\\Program Files..."
public string AlternateExePath = "%ProgramFiles%\\..."
}
Noteworthy: I'm quite new with SpecFlow.
I can't figure it out why my test fails with [BeforeFeature] and works fine with [BeforeScenario].
It would be great if somebody could help me with this issue. Thanks!
I ran into a similar problem recently. Not sure if this can still help you, but it may be of use for people who stumble upon this question.
For BeforeFeature\AfterFeature to work, the feature itself needs to be tagged, tagging just specific scenarios will not work.
Your feature files should start like this:
#setup_feature
Feature: Name Of Your Feature
#setup_scenario
Scenario: ...

Nunit 2.6.2 Suite running twice instead of once

using System;
using System.Collections;
using NUnit.Framework;
namespace Tests.MyTest
{
public class SpikeSuite
{
[Suite]
public static IEnumerable Suite
{
get
{
var suite = new ArrayList
{
new SpikeTest(),
};
return suite;
}
}
}
[TestFixture]
public class SpikeTest
{
[SetUp]
public void Setup()
{
Console.WriteLine("Test setup");
}
[TestFixtureSetUp]
public void FixtureSetup()
{
Console.WriteLine("Test fixture setup");
}
[Test]
public void TestMethod()
{
Console.WriteLine("Test method");
}
}
}
When I run the above mentioned fixture the output I get is:
Test fixture setup
.Test setup
Test method
Test fixture setup
.Test setup
Test method
How is it that the test setup, fixture setup and test method being executed twice?
Check that your test project is not referenced by another test project. In that case it will appear in two bin folders and be run twice.
Uninstalling the NUnit Test Adapter and re-installing fixed this issue for me.
In Visual Studio > Tools > Extensions and Updates > Remove NUnit Test Adapter then re-install it

Resources