How to modify domain mapping on grails before test executions - unit-testing

Thanks in advance for your help!!
I have to change the sequence of Domain object, cause when is working according some environment variable, de PK will be assigned by sequence ( its value will be over 100M , and if it's working with another "scope", I will have to setup the PK of the same domain ( It`s about from a migrated process, so the PK inserted will be from 40M to 90M, it's on demand process):
As an example:
static mapping = {
if (System.getenv("MIGRATOR")) {
id generator: 'assigned'
}else{
id generator: 'sequence', params: [sequence: 'MY_SEQ']
}
}
And I would like with my integration test do something like:
void "test ..." {
System.metaclass.'static'.getenv = {return (it.equals(MIGRATOR))}
..stuff test about migration and thing related to insert add hoc Domain instance.
}
But I realize that environment is setting up before test running.. so I don't see another way..
Note: I do Integration test cause is an transactional code, with withTransactions functions, so as unit test, it doesn't work , I do it in this way, but, I hear another propose so I can change my point of view to test it.

If you just want to make sure that your mapping is correct with your env variables, you can do a integration test, and inspect your domain class mapping though the org.codehaus.groovy.grails.orm.hibernate.cfg.Mapping instance:
Mapping mapping = new GrailsDomainBinder().getMapping(MyDomainClass)
println mapping.getIdentity() //id[generator:sequence, column:id, type:class java.lang.Long]
Another option is to set your variable in your cmd / console before running the test, take the advantage of running a single test in grails:
set MIGRATOR=true
grails test-app -integration package.TestSpec

Related

How to config environment before running automated tests?

I need a good practice to deal with my issue.
The issue is: I need to run automatic tests against a site. The site has different configurations that completely change its design (on some pages). For example I can config 2 different pages of login. And I need to test them both.
First of all I must make sure that a correct test is run against a correct configuration. So before each test I need to change site's config. It is not good if I have a thousand of test.
So a solution that comes to my mind is to not reconfigure the site each time but do it once and run all the tests that are corresponding to this configuration. But this solution doesn't seems to me as an easy one to make.
For now what I did is: I created a method that is run once before all the other tests and in this method I configure the site to make config that are used in the majority of the tests. All the other tests for now change the config before execution and after execution they change it back. It's not good at all.
To do so I used NUnit3 SetUpFixture and OneTimeSetUp attributes:
/// <summary>
/// Runs once before all the test in order to config the environment
/// </summary>
[SetUpFixture]
public class ConfigTests
{
[OneTimeSetUp]
public void RunBeforeAnyTests()
{
IWebDriver driver = new ChromeDriver();
try
{
//Here I config the stie
CommonActions actions = new CommonActions(driver);
actions.SwitchOffCombinedPaymentPage();
driver.Dispose();
}
catch (Exception)
{
driver.Dispose();
}
}
}
What I thought after this is that I'll be able to send parameters to SetUpFixture but first of all it's impossible and second of all it won't resolve the problem as this feature will just be run twice and the tests will be run against the last configuration.
So guys, how to deal with a site testing that has a lot of configurations?
I'd use a test run parameter from the command-line (or in the .runsettings file if you are using the VS adapter) Your SetUpFixture can grab that parameter and do the initialization and any individual fixtures that need it can grab it as well.
See the --params option to nunit3-console and the TestContext.TestParameters property for accessing the values.
This answers your "first of all it's impossible" part. I didn't answer "second of all... " because I don't understand it. I'll add more if you can clarify.

Ember/Emberfire + Firebase 3 Acceptance Test

Prior to firebase 3 update our acceptance test have been running without any issues. We use the following in our beforeTest and afterTest
moduleForAcceptance('Acceptance | Dashboard | Items | Library | New', {
beforeEach() {
stubFirebase();
var ref = createOfflineRef(basicDataRef, 'https://MY-APP.firebaseio.com');
replaceAppRef(this.application, ref);
stubValidSession(this.application, {uid: 'xxxx'});
},
afterEach() {
unstubFirebase();
}
});
basicDataRef is a fixture for the test. The above code allows my to mock session following the test-helper in torii library to allow my application to correctly obtain the data needed as my firebase hieararchy is as follows:
/
+--uid
+--profile
+--otherdata
I am not testing for permission rules, just interaction to save/edit data in the application, and this has worked OK prior to firebase 3 migration. After version 3 all my test returns the following:
actual: >
false
expected: >
true
stack: >
at http://localhost:7357/assets/test-support.js:4130:12
at exports.default._emberTestingAdaptersAdapter.default.extend.exception (http://localhost:7357/assets/vendor.js:49473:7)
at onerrorDefault (http://localhost:7357/assets/vendor.js:41461:24)
at Object.exports.default.trigger (http://localhost:7357/assets/vendor.js:62212:11)
at http://localhost:7357/assets/vendor.js:63463:40
at Queue.invoke (http://localhost:7357/assets/vendor.js:10415:16)
message: >
Error: permission_denied at /xxxx/profile: Client doesn't have permission to access the desired data.
I always thought the createOfflineRef in emberfire allows us to bypass rules checking. the fact that it keeps returning permission_denied is quite perplexing. Maybe i need to re-engineer the test? Or I approach this wrongly all this time? Any input is greatly appreciated
Got to the bottom of this, and I guess I'll answer my own questions in case somebody else experience the same issue as I have.
the new firebase InitializeApp method has an additional optional parameter called name. By default, Emberfire service sets this name to be:
export const DEFAULT_NAME = '[EmberFire default app]';
However the Emberfire test helper to create firebase offline ref stubs the firebase instance with a different instance name to be:
export const DEFAULT_NAME = '[EmberFire offline test app]';
This cause my test to fail with permission denied, as the acceptance test is attempting to connect to the '[EmberFire default app]' and the stubbed offline reference is called something else.
Creating my own create-offline-ref helper substituting the DEFAULT_NAME to '[EmberFire default app]' solves the problem. I'm not sure as to what is the best practice for acceptance test as the change seems deliberate on emberfire.

Fluent NHibernate - PersistenceSpecification of HiLo scheme

Not sure if I'm asking the right question so please bear with me! Bit of an NHibernate noob.
We're using Fluent NH and have the following id generation scheme for all tables
public class IdGenerationConvention : IIdConvention
{
public void Apply(IIdentityInstance instance)
{
var where = string.Format("TableKey = '{0}'", instance.EntityType.Name);
instance.GeneratedBy.HiLo("HiloPrimaryKeys", "NextHighValue", "1000", x => x.AddParam("where", where));
}
}
We have an SQL script that generates the HiloPrimaryKeys table and seeds it with data which gets run during deployment. This is working fine.
I'm now trying to write unit tests to verify our persistence layer, ideally using SQLite in memory configuration for speed. This is how I configure NH for the tests:
[SetUp]
public void SetupContext()
{
config = new SQLiteConfiguration()
.InMemory()
.ShowSql()
.Raw("hibernate.generate_statistics", "true");
var nhConfig = Fluently.Configure()
.Database(PersistenceConfigurer)
.Mappings(mappings =>
mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>()
.Conventions.AddFromAssemblyOf<IdGenerationConvention>());
SessionSource = new SessionSource(nhConfig);
Session = SessionSource.CreateSession();
SessionSource.BuildSchema(Session);
}
The problem is I don't know how to tell NHibernate about our deployment script so that it generates the correct schema and seed data during tests.
The specific problem I get is when running the following PersistenceSpecification test:
[Test]
public void ShouldAddDocumentToDatabaseWithSimpleValues()
{
new PersistenceSpecification<Document>(Session)
.CheckProperty(x => x.CreatedBy, "anonymous")
.CheckProperty(x => x.CreatedOn, new DateTime(1954, 12, 23))
.CheckProperty(x => x.Reference, "anonymous")
.CheckProperty(x => x.IsMigrated, true)
.CheckReference(x => x.DocumentType, documentType)
.VerifyTheMappings();
}
Which throws the following exception:
TestCase ... failed:
Execute
NHibernate.Exceptions.GenericADOException:
could not get or update next value[SQL: ]
---> System.Data.SQLite.SQLiteException: SQLite error
no such column: TableKey
So my deduction is that it hasn't run the deployment script when checking the persistence spec.
Is there an existing solution to this situation? My Google-fu seems to have deserted me on this one.
As Brian said, you can run the deployment script after the schema is built. This code works well for me:
var config = new SQLiteConfiguration()
.InMemory()
.ShowSql()
.Raw("hibernate.generate_statistics", "true");
var nhConfig = Fluently.Configure()
.Database(config)
.Mappings(mappings =>
mappings.FluentMappings.AddFromAssemblyOf<DocumentMap>()
.Conventions.AddFromAssemblyOf<IdGenerationConvention>());
var SessionSource = new SessionSource(nhConfig);
var Session = SessionSource.CreateSession();
SessionSource.BuildSchema(Session);
// run the deployment script
var deploymentScriptQuery = Session.CreateSQLQuery("ALTER TABLE HiloPrimaryKeys ADD COLUMN TableKey VARCHAR(255); INSERT INTO HiloPrimaryKeys (TableKey, NextHighValue) values ('Document', 1);");
deploymentScriptQuery.ExecuteUpdate();
The deployment script could be loaded from file etc...
Building FNH configuration and database schema is time consuming action. Execution of test suit will take unacceptable amount of time if the count of tests that are using the schema grows and the schema and the configuration are built by each test class. Both configuration and schema should be shared between all tests. Here is how to achieve that without loosing test isolation.
EDIT:
If more than one session instance is required in test then connection pooling should be turned on, or both sessions should be created via the same connection. Details here...
Disclaimer: I'm not an NHibernate user...
...But one possible workaround would be to run your deployment script (or some variation of it) in your test's Setup method (using a shell execute/Process.Start) or to run it in your build script just before you run these tests. You may need to add cleanup in this case if you want a fresh database each test.
We have an SQL script that generates the HiloPrimaryKeys table and seeds it with data which gets run during deployment. This is working fine.
Can you create an entity that gets mapped that represents this HiloPrimaryKeys table and fill this table before your tests start? You could put this in a base class that all your other tests inherit from so that you wouldn't have to add this to every testing class.
This is similar to Brian's solution but instead this table will be created when you do your automapping just like the rest of your tables.

How do I Unit Test the Output of a View in MonoRail?

I've been trying to write some initial NUnit unit tests for MonoRail, having got some basics working already. However, while I've managed to check whether a Flash["message"] value has been set by a controller action, the BaseControllerTest class doesn't seem to store the output for a view at all, so whether I call RenderView or the action itself, nothing gets added to the Response.OutputContent data.
I've also tried calling InPlaceRenderView to try to get it to write to a StringWriter, and the StringWriter also seems to get nothing back - the StringBuilder that returns is also empty.
I'm creating a new controller instance, then calling
PrepareController(controller,"","home","index");
So far it just seems like the BaseControllerTest is causing any output to get abandoned. Am I missing something? Should this work? I'm not 100% sure, because while I'm also running these unit tests in MonoDevelop on Linux, although MonoRails is working OK there.
While I haven't got an ideal method for testing Views, this is possibly less important when ViewComponents can be tested adequately. To test views within the site itself, I can use Selenium. While in theory that can be made part of an NUnit test suite, that didn't run successfully under MonoDevelop in my tests (failing to start the connection to Selenium RC consistently, despite the RC interactive session working fine). However, the Selenium tests can be run as a set from Firefox, which is not too bad - unit testing with NUnit, then Integration/System testing scripting using a Selenium suite, and that setup will work in a Linux/MonoDevelop setup.
As for testing the underlying elements, you can check for redirections and check the flash value set or the like, so that's all fine, and for testing ViewComponents the part-mocked rendering does return the rendered output in an accessible form, so they've proved much easier to test in NUnit (with a base test class of BaseViewComponentTest) as follows:
[Test]
public void TestMenuComponentRendersOK()
{
var mc = new MenuComponent();
PrepareViewComponent(mc);
var dict = new System.Collections.Specialized.ListDictionary();
dict.Add("data",getSampleMenuData());
dict.Add("Name","testmenu");
// other additional parameters
mc.RenderComponent(mc,dict);
Assert.IsTrue(this.Output.Contains(""),"List items should have been added");
}

How to use "Pex and Moles" library with Entity Framework?

This is a tough one because not too many people use Pex & Moles or so I think (even though Pex is a really great product - much better than any other unit testing tool)
I have a Data project that has a very simple model with just one entity (DBItem). I've also written a DBRepository within this project, that manipulates this EF model. Repository has a method called GetItems() that returns a list of business layer items (BLItem) and looks similar to this (simplified example):
public IList<BLItem> GetItems()
{
using (var ctx = new EFContext("name=MyWebConfigConnectionName"))
{
DateTime limit = DateTime.Today.AddDays(-10);
IList<DBItem> result = ctx.Items.Where(i => i.Changed > limit).ToList();
return result.ConvertAll(i => i.ToBusinessObject());
}
}
So now I'd like to create some unit tests for this particular method. I'm using Pex & Moles. I created my moles and stubs for my EF object context.
I would like to write parametrised unit test (I know I've first written my production code, but I had to, since I'm testing Pex & Moles) that tests that this method returns valid list of items.
This is my test class:
[PexClass]
public class RepoTest
{
[PexMethod]
public void GetItemsTest(ObjectSet<DBItem> items)
{
MEFContext.ConstructorString = (#this, name) => {
var mole = new SEFContext();
};
DBRepository repo = new DBRepository();
IList<BLItem> result = repo.GetItems();
IList<DBItem> manual = items.Where(i => i.Changed > DateTime.Today.AddDays(-10));
if (result.Count != manual.Count)
{
throw new Exception();
}
}
}
Then I run Pex Explorations for this particular parametrised unit test, but I get an error path bounds exceeded. Pex starts this test by providing null to this test method (so items = null). This is the code, that Pex is running:
[Test]
[PexGeneratedBy(typeof(RepoTest))]
[Ignore("the test state was: path bounds exceeded")]
public void DBRepository_GetTasks22301()
{
this.GetItemsTest((ObjectSet<DBItem>)null);
}
This was additional comment provided by Pex:
The test case ran too long for these inputs, and Pex stopped the analysis. Please notice: The method Oblivious.Data.Test.Repositories.TaskRepositoryTest.b__0 was called 50 times; please check that the code is not stuck in an infinite loop or recursion. Otherwise, click on 'Set MaxStack=200', and run Pex again.
Update attribute [PexMethod(MaxStack = 200)]
Question
Am I doing this the correct way or not? Should I use EFContext stub instead? Do I have to add additional attributes to test method so Moles host will be running (I'm not sure it does now). I'm running just Pex & Moles. No VS test or nUnit or anything else.
I guess I should probably set some limit to Pex how many items should it provide for this particular test method.
Moles is not designed to test the parts of your application that have external dependencies (e.g. file access, network access, database access, etc). Instead, Moles allows you to mock these parts of your app so that way you can do true unit testing on the parts that don't have external dependencies.
So I think you should just mock your EF objects and queries, e.g., by creating in-memory lists and having query methods return fake data from those lists based on whatever criteria is relevant.
I am just getting to grips with pex also ... my issues surrounded me wanting to use it with moq ;)
anyway ...
I have some methods similar to your that have the same problem. When i increased the max they went away. Presumably pex was satisfied that it had sufficiently explored the branches. I have methods where i have had to increase the timeout on the code contract validation also.
One thing that you should probably be doign though is passing in all the dependant objects as parameters ... ie dont instantiate the repo in the method but pass it in.
A general problem you have is that you are instantiating big objects in your method. I do the same in my DAL classes, but then i am not tryign to unit test them in isolation. I build up datasets and use this to test my data access code against.
I use pex on my business logic and objects.
If i were to try and test my DAL code id have to use IOC to pass the datacontext into the methods - which would then make testing possible as you can mock the data context.
You should use Entity Framework Repository Pattern: http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx