Arquillian persistence extension - #UsingDataset seed once for all tests - jboss-arquillian

I have a JPA based application that is read only from the database, it therefore makes sense only to seed the database once before the tests start. Is it possible to do this using the Arquillian persistence extension? I believe it is trying to reseed/clean for every test?
I have tried the following
#RunWith(Arquillian.class)
#UsingDataset("mydataset.xml")
#Cleanup(phase = TestExecutionPhase.NONE)
public class MyArquillianTest {
//Deployable method and tests
}
I've also set the defaultDataSeedStrategy to REFRESH in the arquillian.xml.

Related

How to access TestContext in Specflow 3.0 [BeforeTestRun] static Hook

I have started using Specflow 3.0 for .NET core tests project with built-in MSTest runner.
I encountered problem while trying to setup one-time method execution in order to persist bearer token value for all running tests in Specflow.
So my idea was to create [BeforeTestRun] Hook static method which would make HTTP request with given credentials. The problem is that those credentials are stored in .runsettings file, so I need to have MSTest's TestContext object in order to access dictionary property.
In Scenario's I'm injecting TestContext and it works fine, however I do not know how to access this object in static [BeforeTestRun] method. Is there any chance to create this object myself and store in static property?
As you see this is abstract class, so I guess Test Framework is automatically injecting concrete implementation in Scanarios with DI. How could I get this concrete implementation?
If solution is not present, would you suggest another approach how could I store configurable settings besides .runsettings so I could access them in static [BeforeTestRun] method without DI?
Thank you
AFAIK I know the behaviour of TestContext in MSTest, you get in plain MSTest for every test your own instance of TestContext.
So you can't get an instance for the whole testrun.
What you could do is, that you do the HTTP request in the BeforeScenario hook of the first scenario that gets executed. There you can get to the TestContext instance without problems.

Integration testing when the data layer has multiple implementations

I have a Kotlin/Vertx API as follows with a graphDB based data repository is injected:
class MyServiceAPI : AbstractVerticle() {
//dependency injection using KodeIn
val graphRepository: GraphRepository = kodein.instance()
fun addFriend (friend: User) {
graphRepository.addFriend(friend)
}
}
GraphRepository has several implementations like OrientDBGraphRepository, JanusGraphRepository etc.
I want to add integration tests using in-memory DB instances. I have following questions:
Do I need to write separate integration tests for each DB implementation or should I pass the params(hostname, user, password) of the DB configuration to change the implementation accordingly?
Since I have coded for the repo interface, do I need to I instantiate each implementation for each case when testing them?
Apologies if this is opinion based, any insight would be appreciated.

Unit Testing an SOA WCF system...finding it difficult to get decent coverage

We are currently replacing a 20 year old C based system with a modern SOA WCF system built in .NET3.5. Our industry requires rigorous testing including good automated unit test converage. We are having issues, however unit testing our SOA system to anywhere near the extent that the C based system was unit tested.
The single biggest problem is that most of the methods in the system are actually dependant on calling into code across service boundaries, for example we are heavily data driven but we don't access the database directly within our system: we call into a WCF Data Access Service.
Running any unit tests in visual studio is almost impossible as doing almost anything results in cross service calls of some kind. If its not data access its one of the other services. I reckon we can get about 5% coverage.
I see alot of people struggle with testing SOA so I take it this is not unique to us. The thing is QA is going to question why we are not unit testing more of the system.
To be honest I see VSTS unit testing as more of a regression testing than a validation (fit for use) tool. What options are there for unit testing SOA? Is it realistic in peoples experience to achieve good coverage? Is there a way to mock a Data Access Service (or any service: NOTE we dont use WCF proxies) or do we have to explain to QA that unit testing ability has gone backwards over the last 20 years...
Any sort of suggestions are welcome, I guess this is a general opinion question.
I'd have to say that unit-testing an SOA is a lot like unit-testing anything else. If anything it should be easier because it forces you to isolate dependencies.
Unit tests shouldn't generally cross service boundaries. Really, the idea of a service is that it is completely independent and opaque. You test the service directly - not over the WCF channel, but by unit-testing the actual classes that compose the service. Once you've tested the service itself (which you should be able to get near 100% coverage), you don't need to involve it in client-side tests.
For client-side unit tests, you mock the service. WCF actually makes this very easy for you because every WCF client implements an interface; if you normally use the FooService or FooServiceSoapClient in your code, change it to use the corresponding IFooService or FooServiceSoap that the proxy class implements. Then you can write your own MockFooService that implements the same interface and use that in your client tests.
Part of what sometimes trips people up here is the idea that the service can do wildly different things depending on the specific message. However, a client test that involves the service interface should generally only be testing one or two specific messages per test, so it's easy to mock the exact request/response you need for a given client test using a tool like Rhino Mocks.
Duplex gets a little tricky but keep in mind that duplex services are supposed to be based around interfaces as well; even the MSDN example introduces an ICalculatorDuplexCallback. Callbacks will be interfaces, so just like you can mock the service methods on the client side, you can mock the client callbacks on the service side. Just have mock/fake callbacks that you use for the service unit tests.
Mark Seeman has a pretty good blog post all about Unit-Testing Duplex WCF Clients, with example code and all. You should give that a read, I think it will help you out here.
It sounds like the testing you are doing now is integration tests or system tests. Where the test methods are calling external sources. To truly perform unit testing on a service you will need to somehow abstract the external calls out so you can mock (for example moq) or stub the calls to that service.
For example Code that is tightly coupled to the Data Access Service:
public class SomeSOA
{
public bool DoSomeDataAccess()
{
//call the real data service
DataService dataService = new DataService()
int getANumber = dataService.GetANumber();
return getANumber == 2;
}
}
Slightly refactored to reduce coupling to the DataService
public class SomeSOA
{
IDataService _dataService;
public SomeSOA(IDataService dataService)
{
_dataService = dataService;
}
public SomeSOA() :this(new DataServiceWrapper()){}
public bool DoSomeDataAccess()
{
int getANumber = _dataService.GetANumber();
return getANumber == 2;
}
}
public DataServiceWrapper : IDataService
{
public int GetANumber()
{
// call the real data service
}
}
Now with the re-factored code you can modify your tests to use a stub that can return expected results without calling the real DataService.
[TestMethod]
public void GetANumber_WithAValidReturnedNumber_ReturnsTure()
{
IDataService dataService = new DataServiceFake();
SomeSOA someSoa = new SomeSOA(dataService);
Assert.IsTrue(someSoa.DoSomeDataAccess();
}
public class DataServiceFake :IDataService
{
public int DoSomeDataAccess()
{
//return a fake result from the dataService.
return 2;
}
}
Now granted all of this is just pseudo code, but decoupling your service from the real implamentation of the DataAccessSerive will allow you to unit test your code and not rely on a real DataAccessService for them to perform correctly.
Hope this helps and makes sense!
Here's my suggestion: step away from the "Unit Testing" paradigm, and work on a suite of integration tests.
I assume that your system has a front end which calls the services.
Write a test suite that actually connects to running services (in your test environment obviously) and makes the same sequence of calls as your front end does.
Your test environment would have the latest services running against an empty test database. Just like with unit tests, each test would make the calls that populates the test data with just what it needs, invoke functionality, test that the visible information now matches what it should, then clears the database again.
You may have to create one other service that services the integration tests by clearing the database on request. (Obviously, you wouldn't actually deploy that one...)
While they are not "Unit tests", you would be getting full coverage.

How should I be configuring spring and hibernate so that my Integration Tests replicate properly the behaviour of the Web application?

We have a web application based on NSpring 1.2 and NHibernate 2 and use HibernateTemplate. The web application is configured to use OpenSessionInViewModule.
In our integration tests however the hibernate session is marked as InitDeferredClose and for the most part this works fine for our tests. There are some service functions that work fine in the context of the web application but fail when called from a test harness.
For example : I have one function that creates and updates a number of objects within a transaction. The function is marked with the Transaction attribute but the test fails with the message :
Illegal attempt to associate a collection with two open sessions
When called from the web application the transaction completes successfully
How should I be configuring spring and hibernate so that my Integration Tests replicate properly the functionnality of the Web application ?
You should create a SessionScope instance in the SetUp part of test and then close (dispose) it at the end (TearDown). This should mimic OSIV model quite well. Here's a simplified sample:
using System;
using NHibernate;
using NUnit.Framework;
using Spring.Data.NHibernate.Support;
[TestFixture]
public class OsivKindOfTest
{
private SessionScope scope;
// get LocalSessionFactoryObject from somewhere
// see Spring.Testing.NUnit and auto-injection
private ISessionFactory sessionFactory;
[SetUp]
public void OnSetUp()
{
scope = new SessionScope(sessionFactory, null, true, FlushMode.Never, true);
}
public void TestSomething()
{
// just a dummy demo
Console.WriteLine(sessionFactory.GetCurrentSession().Statistics.EntityCount);
}
[TearDown]
public void TearDown()
{
if (scope != null)
{
scope.Dispose();
}
}
}
This sample expects that Spring's LocalSessionFactoryObject has ExposeTransactionAwareSessionFactory set to true
I have rewritten my integration test fixtures to inherit from the AbstractTransactionalDbProviderSpringContextTests class provided by the Spring testing framework.
This indeed runs each test in its own transaction with a (by default) rollback at the end of the test. Apart from solving the problem of two open sessions, my tests run a lot quicker (no need to clear the database each time).
An important point to keep in mind when using the spring testing framework is that it is necessary to ensure the spring application context of the application code and that of the test framework are the one and the same otherwise the outer transaction and the inner transaction would be created by two different Hibernate Session Factories

NHibernate Passing Session to the Repository

How would I go about passing a session to a repository class?
Let's say that the I have two projects.
1) TestSuite
2) BusinessObjects
The repository is contained in the BusinessObjects project. The NHibernate session is opened in the TestSuite project. Now, I want to use the same session since the TestSuite project starts a transaction on that session. Currently, I am using the following:
var repository = new CustomerRepository(_session);
Of course, this looks ugly! I am thinking somehow a dependency injection framework can be hooked and provide me with the ISession object without having to pass into the repository.
In our WCF Service we actually use a UnitOfWork which wraps a single operation and stores the ISession for that operation.
The repositories know how to get an ISession from the current unit of work they are running under.
In terms of testing we have a base test class that any test class which contains tests that touch the database inherits from. We then control the starting and ending of a unit of work in the testfixturesetup. Has worked fairly well for us once you get use to the fact that in the version of NUnit we use teardown is NOT guaranteed to run (in case of an unhandled exception during setup or the test).