Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/blob/master/20180825.md
Showing posts with label testing. Show all posts
Showing posts with label testing. Show all posts
Saturday, 25 August 2018
PeanutButter.RandomValueGen: the builder pattern & random generation for testing purposes
Monday, 18 September 2017
Fluent, descriptive testing with NExpect
Retrieving the post... Please hold.
If the post doesn't load properly, you can check it out here:
https://github.com/fluffynuts/blog/blob/master/20180918_IntroducingNExpect.md
Monday, 9 January 2017
EF-based testing, with PeanutButter: Shared databases
The
One is the EntityPersistenceTester, which provides a fluent syntax around proving that your data can flow into and out of a database. I'm not about to discuss that in-depth here, but it does allow (neat, imo) code like the following to test POCO persistence:
which prove that an EmailAttachment POCO can be put into, and successfully retrieved from a database, allowing DateTime properties to drift by a second. All very interesting, and Soon To Be Documented™, but not the focus of this entry.
I'd like to introduce a new feature, but to do so, I have to introduce where it can be used. A base class
My focus today is on a feature which can help to eliminate a pain-point I (and others) have experienced with EF testing backed onto a TempDb instance: time to run tests. EF takes a second or two to generate internal information about a database the first time some kind of activity (read/write) to that database is done via an EF DbContext. Not too bad on application startup, but quite annoying if it happens at every test.
However, after some nudging in the right direction by co-worker Mark Whitfeld, I'd like to announce the availability of the
To use, decorate your test fixture:
And run your tests. And see an exception:
So, follow the instructions and add the assembly attribute to the top of your test fixture source file and re-run your tests. Congratulations, you're using a shared instance of a TempDb which will be cleaned up when NUnit is finished, providing, of course, that you don't interrupt the test run yourself (:
PeanutButter.TestUtils.Entity Nuget package provides a few utilities for testing EntityFramework-based code, backed by TempDb instances so you can test that your EF code works as in production instead of relying on (in my experience) flaky substitutions.
One is the EntityPersistenceTester, which provides a fluent syntax around proving that your data can flow into and out of a database. I'm not about to discuss that in-depth here, but it does allow (neat, imo) code like the following to test POCO persistence:
// snarfed from EmailSpooler tests
[Test]
public void EmailAttachment_ShouldBeAbleToPersistAndRecall()
{
EntityPersistenceTester.CreateFor<EmailAttachment>()
.WithContext<EmailContext>()
.WithDbMigrator(MigratorFactory)
.WithSharedDatabase(_sharedTempDb)
.WithAllowedDateTimePropertyDelta(_oneSecond)
.ShouldPersistAndRecall();
}
which prove that an EmailAttachment POCO can be put into, and successfully retrieved from a database, allowing DateTime properties to drift by a second. All very interesting, and Soon To Be Documented™, but not the focus of this entry.
I'd like to introduce a new feature, but to do so, I have to introduce where it can be used. A base class
TestFixtureWithTempDb<T> exists within PeanutButter.TestUtils.Entity. It provides some of the scaffolding required to do more complex testing than just "Can I put a POCO in there?". The generic argument is some implementation of DbContext and it's most useful when testing a repository as it provides a protected GetContext() method which provides a spun-up context of type T, with an underlying temporary database. By default, this is a new, clean database every test, but you can invoke the protected DisableDatabaseRegeneration() method in your test fixture's [OneTimeSetup]-decorated method (or constructor, if you prefer) to make this database live for the lifetime of your test fixture. The base class takes care of disposing of the temporary database when appropriate so you can focus on the interesting stuff: getting your tests (and then code) to work. A full (but simple) example of usage can be found here: https://github.com/fluffynuts/PeanutButter/blob/master/source/Utils/PeanutButter.FluentMigrator.Tests/TestDbMigrationsRunner.csMy focus today is on a feature which can help to eliminate a pain-point I (and others) have experienced with EF testing backed onto a TempDb instance: time to run tests. EF takes a second or two to generate internal information about a database the first time some kind of activity (read/write) to that database is done via an EF DbContext. Not too bad on application startup, but quite annoying if it happens at every test.
DisableDatabaseRegeneration() helps, but still means that each test fixture has a spin-up delay, meaning that when there are a few test fixtures, other developers on your team become less likely to run the entire test suite -- which is bad for everyone.However, after some nudging in the right direction by co-worker Mark Whitfeld, I'd like to announce the availability of the
UseSharedTempDb attribute in PeanutButter.TestUtils.Entity as of version 1.2.120, released today.
To use, decorate your test fixture:
[TestFixture]
[UseSharedTempDb("SomeSharedTempDbIdentifier")]
public class TestCrossFixtureTempDbLifetimeWithInheritence_Part1
: TestFixtureWithTempDb
{
// .. actual tests go here ..
}
And run your tests. And see an exception:
PeanutButter.TestUtils.Entity.SharedTempDbFeatureRequiresAssemblyAttributeException :
The UseSharedTempDb class attribute on TestSomeStuff
requires that assembly SomeProject.Tests have the attribute AllowSharedTempDbInstances.
Try adding the following to the top of a class file:
[assembly: PeanutButter.TestUtils.Entity.Attributes.AllowSharedTempDbInstances]
So, follow the instructions and add the assembly attribute to the top of your test fixture source file and re-run your tests. Congratulations, you're using a shared instance of a TempDb which will be cleaned up when NUnit is finished, providing, of course, that you don't interrupt the test run yourself (:
Tuesday, 6 September 2016
Legacy database testing with PeanutButter
Preamble
Recently, I've been asked about a strategy for testing code which works against an existing database. It's not the first time I've been asked about this -- and it probably won't be the last. I should have listened to Scott Hanselman's advice long ago and blogged it.Better late than never, I suppose. Let's get to it!
The problem
You have some code which hits a MSSQL database to do something. It could be hitting a stored procedure for a report. It could be inserting or updating rows. Whatever the use-case, you'd like to have that code under test, if not just for your own sanity, then because you're about to extend that code and are just plain scared that you're about to break something which already exists. This is a valid reason -- and it drove me to the strategy I'll outline below.You may also simply wish to write your code test-first, but have this great existing legacy mass which you have to work with (and around) and you're just struggling to get the first test out.
Please note: this strategy outlines more integration-style testing than true unit testing. However, I'd rather have an integration test than no test any day. This kind of testing also leads to tests which take a few seconds to run (instead of the preferred milliseconds) -- but I'd rather have slow tests than no tests.
Note that I'm tackling MSSQL because:
- It's a common production database
- If you were dealing with simpler databases like SQLite or SQLCE, you may already have a strategy to deal with this (though PB can still make it easier, so read on)
- I haven't found (yet) a nice way to do temporary in-process MySQL or PostgreSQL. You could use this strategy with Firebird since server and embedded can even use the same file (but not concurrently, of course) -- though currently PeanutButter.TempDb has no baked-in Firebird provider. I guess I should fix that!
So, let's really get to it!
The general idea
Ideally, I'd like to have some kind of test framework which would spin up a temporary database, create all the structures (tables, views) that I need, perhaps the programmability (procedures, functions) I'd like to test (if applicable) and also provides a mechanism for loading in data to test against so that I can write "when {condition} then {expectation}"-style tests.I'd also like that temporary database to die by fire when my tests are done. I don't want to have to clean anything up manually.
Traditionally, running instances of database services have been used for this style of testing -- but that leaves you with a few sticky bits:
- Your development and CI environments have to be set up the same, with credentials baked into the test suite. Or perhaps you can use environment overrides -- still, authorization to the test database has to be a concern
- Test isolation is less than trivial and as the test suite grows, the tests start interacting with each other, even if there is cleanup at some point along the way.
- Getting a new developer on the team is more effort than it really should be, mainly because of (1) above. For the same reasons, developing on a "loaner" or laptop is also more effort than it should be. You can't just "check out and go".
- A shared development/test database which accumulates cruft and potentially causes strange test behaviour when unexpected data is matched by systems under test
- Swapping out the production database layer for something like SQLite. Whilst I really like SQLite, the problem boils down to differences in functionality between SQLite and whatever production database you're using. I've come across far to many recently, in a project where tests are run against SQLite and production code runs against PostgreSQL. I've seen similar issues with testing code targeting SQL Server on SQLCE. Even if you have a fairly beefy ORM layer (EF, NHibernate, etc) to abstract a lot of the database layer away from you, you're going to hit issues. I can think of too many to put them out here -- if you really want a list of the issues I've hit in this kind of scenario, feel free to ask. I've learned enough to feel fear when someone suggests testing on a database other than the engine you're going to deploy on.
Sometimes you have tests which work when production code fails. Sometimes your tests simply can't test what you want to do because the test database engine is "differently capable". - For similar reasons to (2) above, even if you're testing down to the ORM layer, mocked / substituted database contexts (EF) can provide you with tests which work when your production code is going to fail.
PeanutButter to the rescue (:
The strategy that emerged
- Create a temporary database (PeanutButter.TempDb.(some flavor))
- Fortunately, when production code is going to be talking to SQL Server, we can use a LocalDb database for testing -- all the functionality of SQL Server (well, pretty-much all of it, enough for application code -- you'll be missing full text search for example, but the engine is basically the same).
- Create the database structures required (via migrations or scripts)
- Run the tests on the parts of the system to be tested
- Dispose of the temporary database when done, leaving no artifacts and no cruft for another test or test fixture.
public void TestSomeLegacySystem
{
[Test]
public void TestSomeLegacyMethod()
{
// Arrange
using (var db = new TempDbLocalDb())
{
using (var conn = db.CreateConnection())
{
// run in database schema script(s)
// insert any necessary data for the test
}
// Act
// write actual test action here
// Assert
using (var conn = db.CreateConnection())
{
// perform assertions on the database with the new connection
}
} // our TempDb is destroyed here -- nothing to clean up!
}
}
This is very raw, ADO-style code. Of course, it's not too difficult to extrapolate to using an EF context since TempDb exposes both a connection string or you could pass a new connection from CreateConnection to your context's constructor, which would call into DbContext's constructor which can take a DbConnection -- and you would set the second (boolean) parameter based on whether or not you'd like to dispose of the connection yourself.
I did this often enough that it became boring and my laziness kicked in. Ok, so that happened at about the third test...
And so TestFixtureWithTempDb was born: this forms a base class for a test fixture requiring a temporary database of the provided type. It has a protected Configure() method which must be used to instruct the base class how to create the database (with an initial migrator to get the database up to speed), as well as providing hints; for example, by default, a new TempDb is spun up for every test, but if you're willing to take care of cleaning out crufty data after each test (perhaps with a [Teardown]-decorated method), then you can share the database between tests in the fixture for a little performance boost. The boost is more noticable when you also have EF talking to the temporary database as EF will cache model information per database on first access -- so even if you have the same structures in two different iterations, EF will go through the same mapping steps for each test, adding a few seconds (I find typically about 2-5) per test.
Indeed, if you have an EF context, you perhaps want to step one up the chain to EntityPersistenceTestFixtureBase, which is inherited with a generic type that is your DbContext. Your implementation must have a constructor which takes just a DbConnection for this base class to function. If you've created your context from EDMX, you'll have to create another partial class with the same name and the expected constructor signature, passing off to an intermediatary static method which transforms a DbConnection into an EntityConnection; otherwise, just add a constructor.
And this is where my laziness kicks in again: the test fixture for EntityPersistenceTestFixtureBase provides a reasonable example for usage. Note the call to Configure() in the constructor -- you could also have this call in a [OneTimeSetup] method. If you forget it, PeanutButter will bleat at you -- but helpfully, instructing you to Configure() the test fixture before running tests (:
Some interesting points:
- Configure's first parameter is a boolean: when true, the configuration will create ASP.NET tables in the temporary database for you (since it's highly unlikely you'll have them in your own migrations). This is useful only if you're intending to test, for example, an MVC controller which will change behaviour based on the default ASP.NET authentication mechanisms. Mostly, you'll want this to be false.
- The second parameter is a factory function: it takes in a connection string and should emit something which implements IDBMigrationsRunner -- this is an instance of a class with a MigratoToLatest() method which performs whatever is necessary to build the required database structures. You could wrap a FluentMigrator instance, or you can use the handy DbSchemaImporter, given a dump of your database as scripts (without the use statement!) to run in your existing schema. When doing the latter, I simply import said script in a regular old .net resource -- when doing so, you'll get a property on that resource which is a string: the script to run (:
- You can configure a method to run before providing an new EF context -- when configured, this method will be given the EF context which is first created in a test so that it can, for example, clear out old data. Obviously, this only makes sense if you're going full-EF.
- If you have a hefty legacy database, expect some minor issues that you'll have to work through. I've found, for instance, procedures which compiled in SSMS, but not when running in the script for said procedure because it was missing a semi-colon. Don't despair: the effort will be worth it. You can also try only scripting out the bare minimum of the target database that is required for your tests.
Enough blathering!
Ok, this has been a post well-worth a TL;DR. It's the kind of thing would would probably work better as a 15-minute presentation, but I suppose some blog post is better than no post (:Questions? Comments? They're all welcome. If there's something you'd like me to go more in-depth with, shout out -- I can always re-visit this topic (:
Legacy database testing with PeanutButter
Preamble
Recently, I've been asked about a strategy for testing code which works against an existing database. It's not the first time I've been asked about this -- and it probably won't be the last. I should have listened to Scott Hanselman's advice long ago and blogged it.Better late than never, I suppose. Let's get to it!
The problem
You have some code which hits a MSSQL database to do something. It could be hitting a stored procedure for a report. It could be inserting or updating rows. Whatever the use-case, you'd like to have that code under test, if not just for your own sanity, then because you're about to extend that code and are just plain scared that you're about to break something which already exists. This is a valid reason -- and it drove me to the strategy I'll outline below.You may also simply wish to write your code test-first, but have this great existing legacy mass which you have to work with (and around) and you're just struggling to get the first test out.
Please note: this strategy outlines more integration-style testing than true unit testing. However, I'd rather have an integration test than no test any day. This kind of testing also leads to tests which take a few seconds to run (instead of the preferred milliseconds) -- but I'd rather have slow tests than no tests.
Note that I'm tackling MSSQL because:
- It's a common production database
- If you were dealing with simpler databases like SQLite or SQLCE, you may already have a strategy to deal with this (though PB can still make it easier, so read on)
- I haven't found (yet) a nice way to do temporary in-process MySQL or PostgreSQL. You could use this strategy with Firebird since server and embedded can even use the same file (but not concurrently, of course) -- though currently PeanutButter.TempDb has no baked-in Firebird provider. I guess I should fix that!
So, let's really get to it!
The general idea
Ideally, I'd like to have some kind of test framework which would spin up a temporary database, create all the structures (tables, views) that I need, perhaps the programmability (procedures, functions) I'd like to test (if applicable) and also provides a mechanism for loading in data to test against so that I can write "when {condition} then {expectation}"-style tests.I'd also like that temporary database to die by fire when my tests are done. I don't want to have to clean anything up manually.
Traditionally, running instances of database services have been used for this style of testing -- but that leaves you with a few sticky bits:
- Your development and CI environments have to be set up the same, with credentials baked into the test suite. Or perhaps you can use environment overrides -- still, authorization to the test database has to be a concern
- Test isolation is less than trivial and as the test suite grows, the tests start interacting with each other, even if there is cleanup at some point along the way.
- Getting a new developer on the team is more effort than it really should be, mainly because of (1) above. For the same reasons, developing on a "loaner" or laptop is also more effort than it should be. You can't just "check out and go".
- A shared development/test database which accumulates cruft and potentially causes strange test behaviour when unexpected data is matched by systems under test
- Swapping out the production database layer for something like SQLite. Whilst I really like SQLite, the problem boils down to differences in functionality between SQLite and whatever production database you're using. I've come across far to many recently, in a project where tests are run against SQLite and production code runs against PostgreSQL. I've seen similar issues with testing code targeting SQL Server on SQLCE. Even if you have a fairly beefy ORM layer (EF, NHibernate, etc) to abstract a lot of the database layer away from you, you're going to hit issues. I can think of too many to put them out here -- if you really want a list of the issues I've hit in this kind of scenario, feel free to ask. I've learned enough to feel fear when someone suggests testing on a database other than the engine you're going to deploy on.
Sometimes you have tests which work when production code fails. Sometimes your tests simply can't test what you want to do because the test database engine is "differently capable". - For similar reasons to (2) above, even if you're testing down to the ORM layer, mocked / substituted database contexts (EF) can provide you with tests which work when your production code is going to fail.
PeanutButter to the rescue (:
The strategy that emerged
- Create a temporary database (PeanutButter.TempDb.(some flavor))
- Fortunately, when production code is going to be talking to SQL Server, we can use a LocalDb database for testing -- all the functionality of SQL Server (well, pretty-much all of it, enough for application code -- you'll be missing full text search for example, but the engine is basically the same).
- Create the database structures required (via migrations or scripts)
- Run the tests on the parts of the system to be tested
- Dispose of the temporary database when done, leaving no artifacts and no cruft for another test or test fixture.
public void TestSomeLegacySystem
{
[Test]
public void TestSomeLegacyMethod()
{
// Arrange
using (var db = new TempDbLocalDb())
{
using (var conn = db.CreateConnection())
{
// run in database schema script(s)
// insert any necessary data for the test
}
// Act
// write actual test action here
// Assert
using (var conn = db.CreateConnection())
{
// perform assertions on the database with the new connection
}
} // our TempDb is destroyed here -- nothing to clean up!
}
}
This is very raw, ADO-style code. Of course, it's not too difficult to extrapolate to using an EF context since TempDb exposes both a connection string or you could pass a new connection from CreateConnection to your context's constructor, which would call into DbContext's constructor which can take a DbConnection -- and you would set the second (boolean) parameter based on whether or not you'd like to dispose of the connection yourself.
I did this often enough that it became boring and my laziness kicked in. Ok, so that happened at about the third test...
And so TestFixtureWithTempDb was born: this forms a base class for a test fixture requiring a temporary database of the provided type. It has a protected Configure() method which must be used to instruct the base class how to create the database (with an initial migrator to get the database up to speed), as well as providing hints; for example, by default, a new TempDb is spun up for every test, but if you're willing to take care of cleaning out crufty data after each test (perhaps with a [Teardown]-decorated method), then you can share the database between tests in the fixture for a little performance boost. The boost is more noticable when you also have EF talking to the temporary database as EF will cache model information per database on first access -- so even if you have the same structures in two different iterations, EF will go through the same mapping steps for each test, adding a few seconds (I find typically about 2-5) per test.
Indeed, if you have an EF context, you perhaps want to step one up the chain to EntityPersistenceTestFixtureBase, which is inherited with a generic type that is your DbContext. Your implementation must have a constructor which takes just a DbConnection for this base class to function. If you've created your context from EDMX, you'll have to create another partial class with the same name and the expected constructor signature; otherwise, just add a constructor.
And this is where my laziness kicks in again: the test fixture for EntityPersistenceTestFixtureBase provides a reasonable example for usage. Note the call to Configure() in the constructor -- you could also have this call in a [OneTimeSetup] method. If you forget it, PeanutButter will bleat at you -- but helpfully, instructing you to Configure() the test fixture before running tests (:
Some interesting points:
- Configure's first parameter is a boolean: when true, the configuration will create ASP.NET tables in the temporary database for you (since it's highly unlikely you'll have them in your own migrations). This is useful only if you're intending to test, for example, an MVC controller which will change behaviour based on the default ASP.NET authentication mechanisms. Mostly, you'll want this to be false.
- The second parameter is a factory function: it takes in a connection string and should emit something which implements IDBMigrationsRunner -- this is an instance of a class with a MigratoToLatest() method which performs whatever is necessary to build the required database structures. You could wrap a FluentMigrator instance, or you can use the handy DbSchemaImporter, given a dump of your database as scripts (without the use statement!) to run in your existing schema. When doing the latter, I simply import said script in a regular old .net resource -- when doing so, you'll get a property on that resource which is a string: the script to run (:
- You can configure a method to run before providing an new EF context -- when configured, this method will be given the EF context which is first created in a test so that it can, for example, clear out old data. Obviously, this only makes sense if you're going full-EF.
- If you have a hefty legacy database, expect some minor issues that you'll have to work through. I've found, for instance, procedures which compiled in SSMS, but not when running in the script for said procedure because it was missing a semi-colon. Don't despair: the effort will be worth it. You can also try only scripting out the bare minimum of the target database that is required for your tests.
Enough blathering!
Ok, this has been a post well-worth a TL;DR. It's the kind of thing would would probably work better as a 15-minute presentation, but I suppose some blog post is better than no post (:Questions? Comments? They're all welcome. If there's something you'd like me to go more in-depth with, shout out -- I can always re-visit this topic (:
Wednesday, 3 June 2015
A little PeanutButter housekeeping
PeanutButter, that collection of libraries that does a whole bunch of stuff, has always been extended with the philosophy that it would be better to have a bunch of small libraries each with only their own dependencies rather than a monolithic installation of a bunch of crap you'd never want.
Well, with the exception of PeanutButter.TestUtils.Generic, which is where interesting test helper code went to lurk and generally be useful. This was where the first incarnation of TempDb was born. It was either Sqlite or SqlCe, I don't remember, but whichever it was, the other was soon to follow, in the same package. So if you wanted a temporary SqlCe database, you ended up getting all of the Sqlite dependencies smooshed into your project. Boo!
I recognised this as sub-optimal, but left it just so, partly because I'm a lazy bugger and partly because I was afraid of fallout for anyone who might upgrade packages and find stuff to be no longer working as it had been moved out into another package.
Not too long ago, I got the itch to add LocalDb support and, of course, it ended up in the same assembly. I was getting less stoked, but remained at the same level of lazy.
Finally, tonight, I got my ass in gear and split these out. So there are 4 new packages:
Anyway, as always, they're totally free. So if they break, you can keep all the pieces.
Well, with the exception of PeanutButter.TestUtils.Generic, which is where interesting test helper code went to lurk and generally be useful. This was where the first incarnation of TempDb was born. It was either Sqlite or SqlCe, I don't remember, but whichever it was, the other was soon to follow, in the same package. So if you wanted a temporary SqlCe database, you ended up getting all of the Sqlite dependencies smooshed into your project. Boo!
I recognised this as sub-optimal, but left it just so, partly because I'm a lazy bugger and partly because I was afraid of fallout for anyone who might upgrade packages and find stuff to be no longer working as it had been moved out into another package.
Not too long ago, I got the itch to add LocalDb support and, of course, it ended up in the same assembly. I was getting less stoked, but remained at the same level of lazy.
Finally, tonight, I got my ass in gear and split these out. So there are 4 new packages:
- PeanutButter.TempDb
- PeanutButter.TempDb.Sqlite
- PeanutButter.TempDb.SqlCe
- PeanutButter.TempDb.LocalDb
Anyway, as always, they're totally free. So if they break, you can keep all the pieces.
Thursday, 7 May 2015
PeanutButter TempDb gets LocalDb support
PeanutButter.TestUtils.Generic contains a lot of stuff, including TempDb<>, a generic abstract class which can be used to create temporary database instances and two derivatives, TempDbSqlite and TempDbSqlCe which, as the names might suggest, provide temporary databases of the Sqlite and SqlCe flavours.
Tonight, I added TempDbLocalDb which uses SQL Server's LocalDB mode (as is the default mechanism for MVC web applications. Whilst this does seem to take a little longer to spin up, it means that your tests can now have full SQLServer support with a temporary database which is automatically cleaned up as your tests end.
TempDb<> implements IDisposable, so the natural flow would be something like:
You can install via nuget with:
install-package peanutbutter.testutils.generic
Hope this is of use to someone. Whilst it's true that providing a repository layer, for example, and mocking out data get/set operations is a lot faster (and probably better design), there are times when you just have to test against a database engine (for example, when testing that your database migrations work and that your entity models align with your migrated database structures... you are testing that, aren't you?)
Update (2015/06/03): the TempDb packages have (finally) been split out and swept up so you don't have to install all of the providers you're not using. Check out the post here: http://davydm.blogspot.com/2015/06/a-little-peanutbutter-housekeeping.html
Tonight, I added TempDbLocalDb which uses SQL Server's LocalDB mode (as is the default mechanism for MVC web applications. Whilst this does seem to take a little longer to spin up, it means that your tests can now have full SQLServer support with a temporary database which is automatically cleaned up as your tests end.
TempDb<> implements IDisposable, so the natural flow would be something like:
using (var db = new TempDbLocalDb())
{
var connection = db.CreateConnection();
connection.Open(); // if you need it open first
// do stuff with the connection
// for example, create an Entity context using the DbConnection
}
Thanks to Andrew Russell for the idea and pointing me at some resources (http://blog.developers.ba/localdb-for-database-integration-testing-in-asp-net-5-project-and-xunit-net/) which got me going.
You can install via nuget with:
install-package peanutbutter.testutils.generic
Hope this is of use to someone. Whilst it's true that providing a repository layer, for example, and mocking out data get/set operations is a lot faster (and probably better design), there are times when you just have to test against a database engine (for example, when testing that your database migrations work and that your entity models align with your migrated database structures... you are testing that, aren't you?)
Update (2015/06/03): the TempDb packages have (finally) been split out and swept up so you don't have to install all of the providers you're not using. Check out the post here: http://davydm.blogspot.com/2015/06/a-little-peanutbutter-housekeeping.html
Subscribe to:
Posts (Atom)
What's new in PeanutButter?
Retrieving the post... Please hold. If the post doesn't load properly, you can check it out here: https://github.com/fluffynuts/blog/...
-
So here's a neat little thing that I learned tonight: how to run a script after a specific package is installed or updated. Why? Bec...
-
There was a time when INI files ruled the world of configuration. Since then, we've been told on numerous occasions by many people that ...
-
Introducing... Peanut Butter! I've been writing code for about 15 years now. It's not really that long, considering the amount of...