I have a scala application with some test using org.scalatest. These test need some global setup (and teardown), in order to manage the test database.
Please don't tell me my tests should not hit the database and I should do it the Java-DAO-Stub-WTF-Overkill-Way™ :-).
I'm running the tests using SBT, which provides a way to execute code before and after test:
testOptions in Test += Tests.Setup( () => println("Setup") )
testOptions in Test += Tests.Cleanup( () => println("Cleanup") )
Unfortunately I cannot access the classes in question there. Unsurprisingly, importing them into build.sbt does not work either.
Any ideas?
You can use the BeforeAndAfterAll or BeforeAndAfter traits, depending upon your needs.
BeforeAndAfterAll:
Trait that can be mixed into suites that need methods invoked before
and after executing the suite. This trait allows code to be executed
before and/or after all the tests and nested suites of a suite are
run.
So in this instance, you would define a MasterSuite which contains all other Suites/Tests, which extends this trait.
BeforeAndAfter:
Trait that can be mixed into suites that need code executed before and
after running each test. This trait facilitates a style of testing in
which mutable fixture objects held in instance variables are replaced
or reinitialized before each test or suite.
Related
I want to use different sets of plugins for different Spock Specifications that extend an abstract BaseSpecification. I am having trouble doing that. From what I read, the #WithPlugin annotation didn't quite seem like what I need. So I've been trying to use JenkinsRule.with(PluginManager).
I'm using the Groovy Spock framework and v2.59 of the Jenkins Unit Test Harness org.jenkins-ci.main:jenkins-test-harness:2.59 to test Jenkins Job DSL that we've written to automate the initialization of our Jenkins instances.
I have a BaseSpecification class where I declare a field #Shared #ClassRule jenkinsRule = new JenkinsRule(). As I understand it, the JenkinsRule is how we interact with the Jenkins Unit Test Harness and the embedded Jenkins instances. This has worked fine in the past for all Specifications that extend BaseSpecification and define their own feature methods.
But when I try to use something like #Shared #ClassRule jenkinsRule = new JenkinsRule().with(getPluginManager()), in the abstract BaseSpecification—where abstract JenkinsRule getPluginManager() is declared—if I return MyPluginManager.INSTANCE for some specs but not others, I keep getting the following error:
class org.jenkinsci.plugins.workflow.job.WorkflowJob is missing its descriptor
java.lang.AssertionError: class org.jenkinsci.plugins.workflow.job.WorkflowJob is missing its descriptor
at jenkins.model.Jenkins.getDescriptorOrDie(Jenkins.java:1600)
at org.jenkinsci.plugins.workflow.job.WorkflowJob.getDescriptor(WorkflowJob.java:421)
at hudson.model.ItemGroupMixIn.createProjectFromXML(ItemGroupMixIn.java:285)
at jenkins.model.Jenkins.createProjectFromXML(Jenkins.java:3989)
at javaposse.jobdsl.plugin.JenkinsJobManagement.createNewItem(JenkinsJobManagement.java:517)
at javaposse.jobdsl.plugin.JenkinsJobManagement.createOrUpdateConfig(JenkinsJobManagement.java:141)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs_closure4(AbstractDslScriptLoader.groovy:204)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedJobs(AbstractDslScriptLoader.groovy:197)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.extractGeneratedItems(AbstractDslScriptLoader.groovy:184)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts_closure1(AbstractDslScriptLoader.groovy:63)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at javaposse.jobdsl.dsl.AbstractDslScriptLoader.runScripts(AbstractDslScriptLoader.groovy:46)
at BaseJobScriptsSpec.generateDslItems(BaseJobScriptsSpec.groovy:241)
at BaseJobScriptsSpec.setupSpec(BaseJobScriptsSpec.groovy:38)
It seems like whichever PluginManager is used first changes state somewhere, either in a temporary file directory or elsewhere, that causes the error on the next test that uses a JenkinsRule with a different PluginManager. As it is now MyPluginManager is just a copy/paste of org.jvnet.hudson.test.TestPluginManager while I get this proof of concept to work.
What am I doing wrong here? Thank you.
EDIT 2021-08-04 Adding link to repo with reproduced error:
https://github.com/matthiasdenu/plugin-manager-bug/blob/main/src/test/groovy/CustomPluginMangerSpecification.groovy#L12
In my spring boot project, I am using MockMVC to test controller(web) layer. But I also have AOP(AspectJ) logic in my project, when I run unit test for controller with MockMVC, the test also triggers AOP code, how can I prevent AOP code to be triggered while running unit test for controller?
#Test
public void testMyControllerMethod() {
...
// myRequest hits an endpoint function of my controller, there is also AOP intercept the function call, how can I disable AOP to be triggered while running test?
mockMVC.perform(myRequest).andExpect(okStatus)
}
Question is in my code comment :)
I have checked this answer, I understand to use the if() expression, but I don't get TestMode.ACTIVE, there is no such thing in Spring boot. If someone could let me know how to check whether code is running unit test or not at runtime, I would know how to prevent AOP logic run as well.
What I meant in the other answer, as Simon already tried to explain to you, is something like this:
package de.scrum_master.app;
public class TestMode {
public static boolean ACTIVE = false;
}
But actually there I also listed a few other options such as environment variables and system properties. If I were you I would use one of those because in your Maven or Gradle build it would be very easy to set properties or environment variables via configuration. Your if() pointcut could access those variables.
Especially in the context of Spring there is an even simpler option: a test application configuration. Just provide a configuration without aspects to your tests. That way you can have different configurations for
production environment,
unit tests (no aspects),
integration tests (e.g. with aspects but different from unit test and production).
et cetera.
The advantage here is that you don't need any if() pointcuts or build any other knowledge about test/production environments into your aspects, which is quite ugly. My other answer only shows what you can do, it does not say it is the best solution.
I'm trying to implement integration testing in my app and have test class like that:
#ExtendWith(value={MyDockerExtension.class})
#ExtendWith(value={SpringExtension.class})
#WebAppConfiguration
#ContextConfiguration(classes={...})
#TestInstance(TestInstance.LifeCycle.PER_CLASS)
public class TestClass{ ... }
Is there any way to make MyDockerExtension execute some code, before whole SpringExtension start working and generate whole Context with Configurationc classes?
I've heard that order in which we declare extensions is the key, but sadly MyDockerExtension that implements BeforeAllCallback, AfterAllCallback executes right before test method and after whole context is loaded. In that situation it's to late to start containers with docker, becuase since whole context is loaded my app already tried to connect to the container.
At first I was skeptical about the order being fixed but you're correct:
Extensions registered declaratively via #ExtendWith will be executed in the order in which they are declared in the source code.
Regarding the MyDockerExtension, you may want to look at the extension point TestInstancePostProcessor, which is called before #BeforeAll. SpringExtension implements it and I guess it's there where it sets up the application context. If you also implement it, you should be able to act before it does.
A simple login and logout selenium test, using pagefactory is created with TestNG and it works fine while running it as a "TestNG" test. I'm migrating it to Maven and came across issues in accessing variables between different classes.
src/main/java
---package:myapp.pages
Homepage.java
LoginPage.java
---package:utilities
CommonUtils.java
DatabaseUtils.java
src/test/java
---package:myapp.test
LoginTest.java (has static variable about test name)
public static String sTestName = "Regression test - Login/Logout"
While using the above variable in LoginPage.java, there is a compilation error. I'm using it as
public static String sName=myapp.test.LoginTest.sTestName;
The compilation error is:
[10,22] package myapp.test does not exist
How to handle this error? Any help would be highly appreciated.
src/main is where your production code lives, src/test is where your test code lives. The production code is to be shipped to the production environment, the test code is not. Hence, the production code should not depend on the test code. Maven enforces this for you (and your IDE will do so accordingly). There should never be a case where your production code needs to depend on something that's only known to the testing code. Now, there are valid scenarios in which you want behavior to be different during tests than it is for production code, and there is many strategies to do so. For example you can use a properties file (and have one with the same name in src/test/resources "magically" override the production one during testing), or use setters to override things just during testing.
I have a test class to which i have added a constructor containing a
method setCaptureScreenShotOnFailure(true)
There is an assert statement which gets failed in this test
But even though there is no screenshot being captured ( i checked the
selenium server directory)
Can anyone explain how to work with this method in
I understand i cannot use this in my setup method and i can only use
in the individual test classes
Is it correct?
Yes this is only for individual class. However, if you want more effective use then you can implement testng then create a screenshot class which extends to testlistener. So that you can capture screenshot during pass or faliure of tests. refer Selenium Testng Screenshot Listener