TestNG. Need to run specific method before all tests and specifiic test after all tests - maven

Used Selenium + TestNG + Maven.
I want to automate testing vulnerabilities using OWASP ZAP. For this I need to start ZAProxyScanner before all tests - execute method before all tests.
public void initZap(){
zapScanner = new ZAProxyScanner(ZAP_PROXYHOST,ZAP_PROXYPORT,ZAP_APIKEY);
zapScanner.clear(); //Start a new session
zapSpider = (Spider)zapScanner;
}
and when all functional tests were executed - run test for searching vulnerabilities
#Test
public void scanning() throws ClientApiException{
spiderWithZap();
setAlertAndAttackStrength();
zapScanner.setEnablePassiveScan(true);
scanWithZap();
}
Method and test located in one class, e.g. public class TestSecurity
Here is sample of my testng.xml with packages containing functional tests
<suite name="Chrome" thread-count="1" parallel="tests" configfailurepolicy="continue">
<test name="chrome">
<parameter name="browser" value="chrome"/>
<packages>
<package name="tests.suiteLogIn"></package>
<package name="tests.suiteSettings"></package>
<package name="tests.suiteSearch"></package>
</packages>
</test>
UPD. post modified code with AfterTest in it.
I use only Before/AfterMethod annotations
#BeforeMethod(alwaysRun=true)
#Parameters({"browser", "environment"})
public void setUp(#Optional ("firefox") String browser, #Optional ("local") String environment, Method method) throws IOException {
System.out.println("Test name: " + method.getName());
WebDriver driver = getMyDriver(browser, environment);
System.setProperty(ESCAPE_PROPERTY, "false");
}
#AfterMethod(alwaysRun=true)
#Parameters("browser")
public void tearDown(#Optional ("firefox") String browser){
DriverMaster.stopDriver();
}
#BeforeSuite
#Parameters("browser")
public void startZap(#Optional ("firefox") String browser){
if(browser.equals("firefox")){
sec.initZap();
}
}
#AfterSuite
#Parameters("browser")
public void scanZap(#Optional ("firefox") String browser) throws ClientApiException{
if(browser.equals("firefox")){
LoginPage lp = new LoginPage(getDriverInstance()).load();
lp.login("name", "pass");
sec.scanning();
}
}

You basically have two options:
Use #BeforeSuite and #AfterSuite and include that in the files to run or make all your classes extend it
Use ITestListener or ISuiteListener and put the setup and teardown code in their before and after methods.
With listeners, one advantage that I can see is if you want to do conditional teardown (scanning) based on some testresults you can control that too.

Related

How to stop #CucumberContextConfiguration with #SpringBootTest from reloading application context between every test?

I've got this problem where my application context is reloaded between every test. I'm wiring in my actual application with functional test properties, wiremock etc. to create a functional test environment. Tests have always run fine but now we've added several it's become painfully slow due to the spring application being re-run everytime. The io.cucumber versions I'm using in my pom for cucumber-spring, cucumber-java, cucumber-junit is 7.11.1.
My Functional Test runner is annotated like this:
#RunWith(Cucumber.class)
#CucumberOptions(
features = "classpath:functional/features",
glue = {"com.iggroup.ds.functional.stepdefinitions"},
monochrome = true,
tags = "#FunctionalTest",
plugin = {"pretty", "html:target/cucumber-html-report", "junit:target/cucumber-xml-report.xml"}
)
public class FunctionalTestRunner {
#BeforeClass
public static void beforeClass() {
prepareEnvironment();
}
private static void prepareEnvironment() {
int applicationPort = SocketUtils.findAvailableTcpPort();
System.setProperty("server.port", String.valueOf(applicationPort));
System.setProperty("spring.active.profiles", "FUNCTIONAL_TEST");
System.setProperty("spring.cloud.config.enabled", "false");
System.setProperty("spring.cloud.config.server.bootstrap", "false");
}
}
Inside my glue package the Cucumber Configuration looks like this:
#AutoConfigureWireMock(port = 8089)
#CucumberContextConfiguration
#SpringBootTest(
classes = {
ServiceApplication.class,
RestClients.class
},
webEnvironment = DEFINED_PORT,
properties = {
"spring.profiles.active=FUNCTIONAL_TEST",
"spring.cloud.config.enabled = false"
}
)
public class FunctionalTestSpringCucumberConfiguration {
}
And lastly the application itself looks like this:
#EnableAsync
#EnableCaching
#EnableConfigServer
#SpringBootApplication
#EnableConfigurationProperties
public class ServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
I had read somewhere before that the presence of #MockBean was causing unexpected refreshes between context although I never found out as to why - but I have none defined. As far as I can tell across the articles I've been reading, this shouldn't refresh my context every time so wondering if there's any way I can force it not to rewire the ServiceApplication.class in between every scenario?
#AutoConfigureWireMock(port = 8089)
By using Wiremock on fixed port you are dirtying the application context. This means a new application context will be created for each test. The code responsible for this prints a warning that you can see in your logs.
if (portIsFixed(testContext)) {
if (log.isWarnEnabled()) {
log.warn("You've used fixed ports for WireMock setup - "
+ "will mark context as dirty. Please use random ports, as much "
+ "as possible. Your tests will be faster and more reliable and this "
+ "warning will go away");
}
testContext.markApplicationContextDirty(DirtiesContext.HierarchyMode.EXHAUSTIVE);
}

How to write script in gradle that execute particular methods?

I am writing a gradle script that runs all tests before making a build.
test {
filter {
includeTestsMatching "*TestAll*"
includeTestsMatching "*ExtensionValidatorTest*"
........
}
}
I have three tests of different versions(v1,v2,v3).
TestAll.java
package .....v1;//v2 for version 2 and v3 for version 3
#RunWith(Suite.class)
#Suite.SuiteClasses({
A.class,
B.class,
......
})
public class TestAll {
#BeforeClass
public static void setUp() {//connection to database
........
}
#AfterClass
public static void tearDown() {//close database connection
........
}
}
When I run gradle test connection to database is broken after execution of a particular TestAll. I do not want to change the TestAll files of any version as they can be run and tested independently. How can I make gradle run only setUp once(of any version)which establishes connection, then run all the TestAll method in v1,v2 and v3 and finally teardown(of any version) which terminates database connection.
Gradle won't help you with this. There are following methods in Gradle DSL:
test {
beforeSuite{...}
afterSuite{...}
}
However, they execute outside of the test runtime scope and intended for logging. You only can achieve this using a testing framework.
TestNG provides a simple solution - #BeforeSuite and #AfterSuite annotations, that are actually run once before and after the entire suite.
Unfortunately, JUnit doesn't have a built-in solution for that, since test isolation is its core concept. Nevertheless, you still can make your own. You need to encapsulate database-related API into a singleton class:
public class DbContainer() {
private static DbContainer container;
private DbContaner() {}
public DbContainer getInstance() {
if (container == null) {
container = new DbContainer()
}
return container;
}
public void openConnection() {
// ...
}
public void closeConnection() {
// ...
}
// here is your database API methods
}
Then you can share this instance between test methods and classes using #ClassRule annotation:
#ClassRule
public static DbContainer db = DbContainer.getInstance();
#Test
public void someTest() {
db.query(...)
}
Note: provided solution is not thread-safe and doesn't suit the parallel execution. Some additional effort is required to achieve it.

Cucumber-spring is not finding Step Definitions

I need help!
so the following code works for me (Pure JUnit code)
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#ContextConfiguration("classpath:/importMasterConfig.xml")
public class FeatureWrittenInJavaUsingSteps {
#Before()
public void setup(){
/*do something*/
}
#After
public void tearDown()
{
/*Do something*/
}
#Autowired
ItemServiceController service;
#Test
public void callingStepFunctionsExample(){
ItemServiceControllerTestsSteps steps = new ItemServiceControllerTestsSteps(service);
steps.I_prepare_a_X_item_for_the_X_dealer("only images and pricing", "furniture");
steps.I_perform_the_X_inventory_service_call("createItem");
steps.I_should_get_the_X_response_code("200");
steps.the_inventory_service_response_result_should_be_a_X_object("Vertical Item");
}
}
However, when I try to run this code using the Cucumber Feature, it can't seem to build correctly. I am assuming I am setting up the project wrong.
Here is my Step code:
#ContextConfiguration("classpath:cucumber.xml")
public class ItemServiceControllerTestsSteps {
//Common variables across steps - currently only local.
private VerticalItem itemToCreate;
private ServiceResponse response;
//Step specific variables.
#Autowired
private ItemServiceController itemService;
public ItemServiceControllerTestsSteps(ItemServiceController service){
itemService = service;
}
#Before()
public void setup(){/*Do something*/}
#After()
public void tearDown(){/*Do Something*/}
#Given("^I prepare a \"(.*)\" item for the \"(.*)\" dealer$")
public VerticalItem I_prepare_a_X_item_for_the_X_dealer(String itemType, String dealerType){ //Step function and factory in one.
/*Do stuff*/}
#When("^I perform the \"(.*)\" inventory service call$")
public void I_perform_the_X_inventory_service_call(String actionType){
/*Do Stuff*/}
#Then("^I should get the \"(.*)\" response code$")
public void I_should_get_the_X_response_code(String codeType){/*Do stuff*/}
#Then("^the inventory service response result should be a \"(.*)\" object$")
public void the_inventory_service_response_result_should_be_a_X_object(String expectedClassType){ /*Do Stuff*/}
}
Here is my cucumber.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cucumber.runtime.java.spring stepDefinitions"/>
<context:annotation-config/>
<import resource="classpath:importMasterConfig.xml"/>
</beans>
Finally here is my Runner Class:
#RunWith(Cucumber.class)
#CucumberOptions(plugin = {"pretty", "rerun:rerun.txt", "html:target/local-html-report/"},
glue = "stepDefinitions.ItemServiceControllerTestsSteps")
public class CucumberRunner {}
If someone can please enlighten me why the JUnit runner works and the cucumber one doesn't I would be a very happy camper!
In the above code, I did a few things wrong but lets cover the big ones.
1) My Glue code String was incorrect, I need to pass in the package name, not the file name (should have been just stepDefinitions)
2) I was using Spring 3 instead of Spring 4 with Cucumber 1.2.2 - The latest Cucumber requires Spring 4.
The other stuff wasn't actually related to Spring and Cucumber.
Step definitions should be instance methods on the step definitions classes, and not class (static) methods.
Step definitions classes are instantiated (on demand) for each scenario, so no state should be leaked between scenarios.

How to use a single Log4Net instance in mutliple Nunit TestFixtures with SetUpFixture

I'm just getting into the use of Selenium Webdriver and its EventFiring so that I can log any exceptions thrown by the driver to a file or email etc.
I have got Log4Net working and my Unit Tests are running fine with Selenium.
What I am having issues with is having Log4Net create 1 log file, but for multiple test fixtures.
Here are some important classes which I think I need to show you in order to explain my issue.
public class EventLogger : EventFiringWebDriver
{
// Not sure if this is the best place to declare Log4Net
public static readonly ILog Log = LogManager.GetLogger(typeof(EventLogger));
public EventLogger(IWebDriver parentDriver) : base(parentDriver)
{
// To get Log4Net to read the configuration file on what logger to use
// To console , file, email etc
XmlConfigurator.Configure();
if (Log.IsInfoEnabled)
{
Log.Info("Logger started.");
}
}
protected override void OnFindingElement(FindElementEventArgs e)
{
base.OnFindingElement(e);
//TODO:
if (Log.IsInfoEnabled)
{
Log.InfoFormat("OnFindingElement: {0}", e);
}
}
protected override void OnElementClicked(WebElementEventArgs e)
{
base.OnElementClicked(e);
//TODO:
if (Log.IsInfoEnabled)
{
Log.InfoFormat("OnElementClicked: {0}", e.Element.GetAttribute("id"));
}
}
}
Here is my SetupFixture - which I THINK is run every time a new TestFixture class is run.
[SetUpFixture]
public class BaseTest
{
protected static readonly ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private FirefoxProfile firefoxProfile;
private IWebDriver driver;
private EventLogger eventLogger;
public IWebDriver StartDriver()
{
Common.WebBrowser = ConfigurationManager.AppSettings["WebBrowser"];
Log.Info("Browser: " + Common.WebBrowser);
switch (Common.WebBrowser)
{
case "firefox":
{
firefoxProfile = new FirefoxProfile { AcceptUntrustedCertificates = true };
driver = new FirefoxDriver(firefoxProfile);
break;
}
case "iexplorer":
{
driver = new InternetExplorerDriver();
break;
}
case "chrome":
{
driver = new ChromeDriver();
break;
}
}
driver.Manage().Timeouts().ImplicitlyWait(Common.DefaultTimeSpan);
// Here is where I start my EventLogger to handle the events from selenium
// web driver, onClick, OnFindingElement etc.
// Is this the best way? Seems a bit messy, lack of structure
return eventLogger = new EventLogger(driver);
}
public EventLogger EventLogger
{
get { return eventLogger; }
}
}
Here is one of the many TestFixtures I have, each one based on a Selenium2 PageObjects
[TestFixture]
public class LoginPageTest : BaseTest
{
private IWebDriver driver;
private LoginPage loginPage;
[SetUp]
public void SetUp()
{
// Where I use the Log from the BaseTest
// protected static readonly ILog Log <-- top of BaseTest
Log.Info("SetUp");
driver = StartDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
loginPage = new LoginPage();
PageFactory.InitElements(driver, loginPage);
}
[Test]
public void SubmitFormInvalidCredentials()
{
Console.WriteLine("SubmitFormInvalidCredentials");
loginPage.UserName.SendKeys("invalid");
loginPage.Password.SendKeys("invalid");
loginPage.SubmitButton.Click();
IWebElement invalidCredentials = driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_ctl02_title"));
Assert.AreEqual("Invalid user name or password", invalidCredentials.Text);
}
}
My Log.txt file is obviously being re-written over and over after each TestFixture is run,
How can I set up my NUnit Testing so that I only run the Log4Net once, so that I can use it in both my EventLogger and TestFixtures?
I have Googled around a lot, maybe its something simple. Do I have some design issues with the structure of my project?
Try out setting explicitly AppendToFile="True" in the log4net configuration for the FileAppender you are using:
<log4net>
<appender name="..." type="log4net.Appender....">
<appendToFile value="true" />
FileAppender.AppendToFile property
Gets or sets a flag that indicates whether the file should be appended
to or overwritten
Regarding [SetupFixture], I believe you are using it in wrong way. It not supposed to mark base class of the each TesFixture by this attribute, this looks messy. You should declare class which considered to be SetupFixture and mark it by [SetupFixture] attribute so it will be called ONCE for all TestFixtures within a given (declaration) namespace.
From NUnit documentation, SetUpFixtureAttribute:
This is the attribute that marks a class that contains the one-time
setup or teardown methods for all the test fixtures under a given
namespace. The class may contain at most one method marked with the
SetUpAttribute and one method marked with the TearDownAttribute

OSGi Declarative Services - NullPointer Exception

I have a problem with my Declarative Services. I have 2 bundles, one is a server provider and another the user interface that consumes the service.
On server side, the implementation is:
public boolean checkUser(){
return true;
}
And the XML file inside OSGi-INF folder:
<component name="ZBService">
<implementation class="service.ZBService" />
<service>
<provide interface="service.IZBService" />
</service>
</component>
On client side, the implementation is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
IZBService zb;
public void setZBService(IZBService eventAdmin) {
this.zb = eventAdmin;
}
public void unsetZBService(IZBService eventAdmin){
if(this.zb == eventAdmin){
this.zb = null;}
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And XML file:
<component name="ZBService">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service>
<reference name="zb" interface="service.IZBService" bind="setZBService" unbind="unsetZBService" cardinality="0..n" policy="dynamic" />
</component>
Also, I have included the tag Service-Component on manifest file and I have deployed the equinox ds bundle that is ACTIVE.
The client is a GWT user interface, then I inject the service reference into server side of GWT. Well, when I deploy the application on Equinox it runs, but when I push the button, I launch an event to call ZBService. I have debugged the application and the error is zb attribute is null. It is to say, the dependence is nos injected. However the services are exposed on Equinox. If I write services on Equinox console, the services are deployed. Then, my conclusion is the error is due to the injection does not perform.
I would like to know if someone knows what is the reason??
Thanks a lot in advance!!
Nice day
EDIT:
I did your suggestions but it doesn't run. I change the component names and condinality/policy. The result is the same --> NullPointerException due to the injection isn't done.
Also I have debug the application to see if the methods bind and/or unbind are called, but they aren't.
The complete class is:
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService{
static protected IZBService zb;
public GreetingServiceImpl(){
System.out.println("Constructor GreetingServiceImpl");
}
public IZBService getZb() {
return zb;
}
public void setZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
public void unsetZb(IZBService zb) {
GreetingServiceImpl.zb = zb;
}
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Cache the current thread
Thread currentThread = Thread.currentThread();
// We are going to swap the class loader
ClassLoader oldContextClassLoader = currentThread.getContextClassLoader();
currentThread.setContextClassLoader(this.getClass().getClassLoader());
super.service(req, resp);
currentThread.setContextClassLoader(oldContextClassLoader);
}
public void activate(ComponentContext context) {
System.out.println("Creating new greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public void activate() {
System.out.println("Activando la referencia al servicio");
}
public void deactivate(ComponentContext context) {
System.out.println("Deactivating greeter for " + context.getProperties().get("name")
+ ": " + context.getComponentInstance().toString());
}
public boolean greetServer(String input, String input2) throws Exception {
return zb.checkUser();
}
}
And the XML client is:
<?xml version="1.0" encoding="UTF-8" ?>
<scr:component name="serviceZB" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<implementation class="main.java.com.gwt.app.server.GreetingServiceImpl" />
<!-- <service>
<provide interface="main.java.com.gwt.app.client.GreetingService"/>
</service> -->
<reference name="zb" interface="service.IZBService"
bind="setZb" unbind="unsetZb" cardinality="1..1"
policy="static" />
</scr:component>
Why isn't the service injected if the service is deployed???
Here is a list of things you can try:
First, remove the "static" of zb, that could be the problem.
If you are using Equinox, add the -Dequinox.ds.print=true flag to the VM arguments and see more information about parsing XMLs and so
Of course, add sysouts to setZB and unsetZB :)
Remember that IZBService implementation needs a constructor without arguments
If you are using Equinox use the "list -c" command to obtain information of each component (it's cool because says exactly why a component is not registered).
Set the "inmediate=true" in XMLs to force to inmediatly activation.
You have both components with the same name, , which is kind of awkward when discussing them.
The reference on the client side has: cardinality="0..n" policy="dynamic". Which means it can be activated with zero to n references. Yet your code does not handle this. It seems to expect exactly one reference. Perhaps you should use cardinality="1..1" policy="static".

Resources