Spring test context setup without SpringJUnit4ClassRunner or AbstractJUnit4SpringContextTests (in Selenium testing) - java

I am setting up JUnit 4.7 tests with Selenium 1.x and Spring 3.0.
I want to extend Selenium's SeleneseTestCase for the shortcuts and conventions it provides (more importantly, the Selenium IDE generated code seems to expect this). Yet I want the Spring context and other goodness to be present during the execution.
Because I cannot extend Spring's AbstractJUnit4SpringContextTests, I tried decorating my test case with #RunWith(SpringJUnit4ClassRunner.class). This succesfully setups Spring but causes some oddities in Selenium execution: tests are executed slowly and browser windows are left open, for example. I suppose it overrides some part of Selenium (just a guess)... unfortunately, the base SeleneseTestCase class only permits altering a restricted set of parameters, exluding setting the execution speed, for example (makes me wonder, if the base class is that nice after all...).
To my understanding, in order to make all the bells and whistles of Spring working, I must either extend the AbstractJUnit4SpringContextTests or decorate the class with #RunWith(SpringJUnit4ClassRunner.class). However, the former I cannot, and the latter brings problems.
Having only #ContextConfiguration does load up the context, but at least dependency injection is not working. That's where I stopped.
How can I initialize Spring neatly with Selenium (or any other library with same case)?
Edit: Made the text more readable.

I was annoyed by a similar problem enough to write a MethodRule implementation that will load a Spring context and autowire it's host test. Maybe that is the start of what you're looking for.
It will allow you to do something like this:
#Rule
public TemporarySpringContext context = new TemporarySpringContext("context.xml");
#Autowired
MyService myServiceBean;
If you make any improvements please let me know.

Related

spring integration test cleanup for conflicting configuration contexts

I'm working on an application where we use integration tests intensively since a core framework we are using operates on the database.
I have test classes using configuration context class such as this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = ConfigA.class)
public A_Test(){
}
The majority of tests are using same context like above. We have over 200+ such tests. But recently we needed some additional configuration for some use cases as well, like this:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {ConfigA.class, ConfigB.class})
public B_Test(){
}
Problem is now when we execute all tests with maven, or IDE runners , loaded cache for ConfigA no longer works. Spring tries to recreate a context for ConfigA which fails because we have H2 DB already configured and Spring tries to create schemas, tables which fails to do so.
To overcome we started to use #DirtiesContext on all tests. Result is over 1H build time, which reduces the developer productivity significantly.
Question: is it possible to clear context for tests like B_Test only? #DirtiesContext(ClassMode=AFTER_CLASS) doesn't help because order of the tests are not guaranteed(and really we don't want to go that way). It fails when type of B_Test tests are last to run. Same for #DirtiesContext(ClassMode=BEFORE_CLASS) visa versa
Is it possible to simulate #DirtiesContext(ClassMode=AFTER_CLASS) and #DirtiesContext(ClassMode=BEFORE_CLASS) at the same time on a bunch of tests?
Or is there any other way to solve in general this problem?
What we tried so far:
Junit Suites : didn't help anything with spring context
ContextHierarchies : didn't help with the case that B_Type tests also dirties the context
Test Ordering: well nobody is really happy about refactoring all the tests to make it work magically
How about using both #DirtiesContext(ClassMode=AFTER_CLASS) and #DirtiesContext(MethodMode=BEFORE_METHOD)?
When you do that, Spring will reload context ConfigA.class and ConfigB.class just before invoking test methods annotated with #DirtiesContext(MethodMode=BEFORE_METHOD).
And then, after all tests of B_Test finished, Spring shutdowns the contexts (and next test class with SpringJUnit4ClassRunner will load its context).
This is essentially a duplicate of Make Spring Boot Recreate Test Databases.
In summary, you likely only need to ensure that you are using unique names for each embedded database that is created using your ConfigA class.
Please read my comments here for details: https://stackoverflow.com/a/28867247/388980
Also, see the comments in SPR-8849 for further details.
Regards,
Sam (author of the Spring TestContext Framework)

Run code before arquillian deployment

I am writing integration tests for a Java EE Servlet using Arquillian + JUnit. I need to be able to execute code before the server launches.
So is it possible to execute code before #Deployment? I tried #BeforeClass with no luck.
The reason I need to do this, is because trust and keystores for ssl needs to exists before the server starts. I am creating the stores problematically and is saving them to files afterwards.
I know a possible workaround would be to have static trust and keystores, but I prefer to create them programmatically before the test starts for full flexibility when writing tests.
There is not really a need to have your own specialization of Arquillian JUnit runner. This solution would be only for JUnit 4.x in that case which you are using for writing your tests.
Arquillian let you hook through extensions mechanism to its runtime and this way you can have some custom logic executed before server startup to provide your keystores. I believe this is more elegant and portable solution.
Please have a look at sample extensions on Github (especially lifecycle would be a good starting point). If you feel like implementing it this way I'm more than happy to help you. The event you might want to observe on is either BeforeSetup or BeforeStart.
You have two other options for executing code before and after your test:
Rules or ClassRules are executed around and before/after
Using a custom Testrunner (extending the default 'Arquillian' runner)
But as the static deployment method is not invoked by a rule, I assume you have to go for the testrunner.

Custom Filter Chain for TestClasses?

I'm using spring-boot and #WebIntegrationTest to run some Selenium tests. I'm trying to figure out how to add/remove some filters for my test cases.
I've gone over the docs a few times and have not been able to find a way to do this. Is it possible?
Please note: I am not using mockMvc and for these test cases we do not want to.
See Reference Spring Boot docs how to register or disable servlet filters. To register one, just implement Filter interface and register it with #Bean annotation.
But, my understanding is that Selenium testing should test application as black box and shouldn't mix testing context with production context. Optionally this testing can happen against production environment.
Personally would include one or two sanity tests into application build itself to make sure it's working end to end. But I wouldn't mix contexts anyway.
Otherwise I would place all the tests into separate project firing requests against PROD or continuous delivery environment.
BTW, I highly recommend looking into Page Object pattern when doing Selenium testing.

Scala library initialization design

I have started an open source Scala project named omniprop. The feature I'm currently exploring is how to allow users of the project to stack JVM-styled property providers. For instance, you may wish to look up properties in java.lang.System, Lift's util.Prop, and Typesafe's Config library. Due to some other constraints/features of omniprop, I need this stack configuration to reside in a known object, so other parts of the library can retrieve properties from this stack.
In order for omniprop to work correctly, this configuration needs to be invoked by the user of the library before any properties are accessed. Hence any project which uses my library will need a bootstrap/initializer which can set up the provider stack. An example of this initial configuration code looks like this:
import com.joescii.omniprop.providers._
PropertyProviders.configure(List(
SystemPropertyProvider,
LiftPropsProvider
))
The challenge I'm facing is with testing in particular. In order for the test code for a project utilizing omniprop to work, it must somehow run the above code before any tests are run. Currently, I don't see a clean way to do this with sbt or any of the testing libraries I am familiar with such as scalatest, scalacheck, or specs2. As it is, one would need to call the above snippet in every test suite, which is certainly not ideal.
Another approach this this problem is what Lift does, in which every project necessarily has a class called bootstrap.liftweb.Boot that the library invokes to set everything up. I find that to be a reasonable approach to a web framework such as Lift, but seems to be too much for a tiny property helper library.
I really have two questions here:
How can I have sbt invoke the above setup code with the correct classloader before all tests run?
More importantly, is this the best design for a library which requires initialization, or is there a better approach?
Using ScalaTest, when I've had to do something similar, I created a trait that extends BeforeAndAfterAll, which I mixed into every suite that needed it.
trait Configure extends Suite with BeforeAndAfterAll {
override def beforeAll() { PropertyProviders.configure(/*...*/); }
override def afterAll() { PropertyProviders.configure(/*...*/); }
}
You just mix it in like any other trait
trait FooSpec extends Spec with Configure {
// ...
}
You could put the initialization code in a trait constructor and have your tests extend from that trait.
Another approach is to have that configuration as the default, and if no configuration is set then it gets used the first time your library code is called. That would cover both testing and non-testing scenarios.
A hybrid approach would be to have your sbt testing configuration set a system property. If that system property is set and no configuration is has been set then the testing config will be used the first time the library code gets called.

Spring Test Configurations

I'm fairly new to Spring and my understanding is a bit scratchy so bear with me and word answers for an idiot.
I've started working on a relatively large, maven based project which has a load of (xml) spring configuration. For this we have a bunch of JUnit tests. At the moment spring configuration for the tests replaces the configuration for the core project modules, which is an issue because it means that if we make changes to the configuration of the main project then those changes aren't reflected in the test module and hence it's possible to get funny test results.
We are currently changing this structure so that the test module configuration overrides (rather than replaces) the main modules configuration. So we only have to override the particular beans we are interested in for each tests.
Is this the best way to do this? Are there alternative ways? Is it possible to fine tune this ever further so that you can override specific setters of a particular bean (rather than the entire bean) for tests?
Any advice is much appreciated.
You can split your main configuration in separate (logical) units and import them into your test configuration as needed.
Keep in mind that Spring 3.1 will introduce XML profiles. This is perfect for testing (with different enviroment specific configurations). It's not finally released yet but I would (and do) use the milestone in new projects.
Ow having to mess with the method to test it is a bit weird by it self in my opinion.
I would avoid that at all if possible, and use spring resources to help you, with dependency injection, different application-contexts for test and dev and mock frameworks you can test almost every thing I can think of.
Maybe you could try to use those.
An example, it's a bit hard to simulate an user security context, but with spring it becomes fairly easy, you just need to create an application-context.xml for the tests (and point to it) and assign a factory in it to create a Bean of Authentication type(it's an interface) and you can use easy mock to automate this bean responses.
But for that to work you have to build your code with that in mind so instead of calling SecurityContext.getContext.... you inject that Authentication Bean from the factory.
In your main configuration separate out all the environment dependent configuration (like datasource, jms connectionfactory etc) to a separate config file - (something like infrastructure-config.xml). The configuration that doesn't change across test & deploy goes into a different file - application-config.xml.
Now for the test only create a new version of the infrastructure config file - test-infrastructure-config.xml and use it with the application-config from the main.

Categories