I worry to much I'm going to wash out due to my age. I'm currently, at the glorious time of writing this post twenty nine years old and by the Lords grace I'm not a year older. And I worry I'm to old for this job. This makes me really unhappy since I have a small boy and I wonder how I'm going to provide for him since I'm no good at anything else (well I'm mediocre at a lots of things, but that is nor here nor there so we are not going event to discuss it) and this is all I have for now.
I don't know a lot of developers older then me, a few older then forty and none older then fifty. I really do not know what is my future career plan. I generally planned to gradually move to an architecture design position, since I'm naturally inclined to it and its not a development heavy thing. As I grow older, and as people grow older, we cannot learn as easily and as much as we could before. New technologies emerge and if you want to stay in this job you need to spend extra time learning them at your own. But later I just can't mange to force my self to find the computer time for it. Sure I read books and blogs, and pay really carefully to code examples for technologies I'm intereseted. Curretnly I'm reading WPF 4 Unleashed by Adam Nathan and Patterns of Enterprise Application Architecture by Martin Folwer, plus I've read the entire MongoDB on-line documentation. But reading is not enough, you got to feel the code bellow your fingers. You just got to. And I really don't to much.
During my holidays I was to washed out to do anything and I told my self its OK you need to rest. But when I got back to work it continued. Sure I started some small coding on the side for learning purpose, I started reading books and blogs and watching presentations but thats just not enough without coding.
What is going on with me you wander. I think a description of my life after work is in order. When I'm finished working I'm with my family helping with the kid, doing house chores the whole nine yards. I put the kid to the bed and around ten o'clock in the evening I'm done with everything. I then go to eat my dinner (yeah I know its kinda late for that, but thats life) take a shower and I'm free to do as I like. I so want to do some coding but when I just think of sitting in from of my computer, my internal will power just crumbles. So I just watch a TV show or read a book. Very depressing, and very unhappy like for me. And then I start to wonder, this is my age doing this to me. Before I didn't have problems with this. Before I could do this all night old. I'm twentynine years old and I can't muster the will power to do this everynight, whats going to happen in ten or twenty years. How I'm going to learn Java or Erlang, or any other technology I'm going to need?
I just don't know and I'm really not happy about it.
29 September 2010
28 September 2010
The shock of it all
Once upon a time when I was 'yay' high (shows to his head, indicating it was very recent) I started writing Selenium tests to test the UI compoenents of my ASP.NET application. As you may know ASP.NET screens are notoriusly not easy to test, expecially if you are lazy (side note: you can extract much of you ASP.NET server side logic in separate classes whithout ties to the ASP.NET application service suing the Class Method pattern.) and the only think a poor developer can do in order to test them (I'm not going into the not testing it at all option or just 'my clicks are enough attitude') is to write some good old UI automation tests.
There is nothing wrong with UI automation tests, mind you, I think they are greate since you are sure you've tested the final integration of your product as shown to the user. What I find appaling is the customers reaction of seeing such tests executed.
Let me tell you - and no, pleas, do not hold your breath - they are blowed away. Amazed. Shocked to the core how good they are. Screens flying, textboxes filled, data showed in grids, filtered and etc. The whole UI testing nine yards. And they want more, they want to start using that in their own projects. It is a presentation ass kicker.
And then we start our fivehundred or more unit-test/functional test suite that executes under a couple of minutes testing almost everything in the application and they are emotionally dead as fish. Oh , its nice can we talk about deadline issues now, please? Right.
I have nothing more to say. I'm appaled. Well, I was anyhow when I was 'yay' high (shows to his head, indicating it was very recent).
There is nothing wrong with UI automation tests, mind you, I think they are greate since you are sure you've tested the final integration of your product as shown to the user. What I find appaling is the customers reaction of seeing such tests executed.
Let me tell you - and no, pleas, do not hold your breath - they are blowed away. Amazed. Shocked to the core how good they are. Screens flying, textboxes filled, data showed in grids, filtered and etc. The whole UI testing nine yards. And they want more, they want to start using that in their own projects. It is a presentation ass kicker.
And then we start our fivehundred or more unit-test/functional test suite that executes under a couple of minutes testing almost everything in the application and they are emotionally dead as fish. Oh , its nice can we talk about deadline issues now, please? Right.
I have nothing more to say. I'm appaled. Well, I was anyhow when I was 'yay' high (shows to his head, indicating it was very recent).
27 September 2010
Mocking real outside dependencies
In a project a while back I realized something about mocking and unit testing. In that project I tried mocking every dependency a object could have. The result was that I could write unit-tests for those objects really fast, and that I could verfy their logic very easily. That was all in the spirit of unit testing.
But something kept me nagging, I though that I wasn't getting enough values from my unit tests. Then I started doing functional tests on my services. Nothing was mocked, since the goal was to test the entire stack. Soon as I wrote a couple of tests defects in my code bellow started poping up. I fixed them and felt really good.
I though back what started me thinking that mocking everything was such a good idea. Well I worked on project where my front end integrated with a web services middle tier and I spend countless hours overtime detecting problems that originated from those services while my code worked fine. I wanted to isolate that big outside dependency so that horrible story would not repeat again.
True to my self I just went to the extreme side and mocked everything. Now, if i change the behavior of one class I will not see what other classes are also affected by the change until I go directly to those classes and change the expected behavior of my changed class mock. This is a problem I have no intention to repeat again.
My new golden rule is : "Nikola, mock only real outside dependencies like web services, databases and the like not your core system objects. It will make you happy."
But something kept me nagging, I though that I wasn't getting enough values from my unit tests. Then I started doing functional tests on my services. Nothing was mocked, since the goal was to test the entire stack. Soon as I wrote a couple of tests defects in my code bellow started poping up. I fixed them and felt really good.
I though back what started me thinking that mocking everything was such a good idea. Well I worked on project where my front end integrated with a web services middle tier and I spend countless hours overtime detecting problems that originated from those services while my code worked fine. I wanted to isolate that big outside dependency so that horrible story would not repeat again.
True to my self I just went to the extreme side and mocked everything. Now, if i change the behavior of one class I will not see what other classes are also affected by the change until I go directly to those classes and change the expected behavior of my changed class mock. This is a problem I have no intention to repeat again.
My new golden rule is : "Nikola, mock only real outside dependencies like web services, databases and the like not your core system objects. It will make you happy."
16 September 2010
Unit Test pattern: Define once, recreate every time
"Define once, recreate every time" is a unit-testing design pattern where all outside dependencies and their default return values of the class being tested are defined once, and then recreated every time a different test is started.
When unit-testing classes which have a complex dependency matrix we use faking a lot. We create fake objects, mock or stubs, we define their behavior in respect to the needs of the test. We need to do that for every test. Sure when a common pattern emerges, we create helper methods in order to remove duplicate code. Sometimes we need to have a lot of these helper methods, sometimes we need none and are happy to create are dependencies manually inside each test method.
When unit testing objects those outside dependencies are not really important. How they behave is not important. What is important is how our logic of the class being tested behaves based on the conditions we set for it.
The main proposition of the "Define once, recreate every time" unit-test pattern is that when defining each dependency there is some common code which needs to be written only once, and there is also a common behavioral state which also needs to be defined only once.
In this pattern all dependencies and their return values are defined as common members of the test fixture, e.g. testing class. Those dependencies are created each time a new before a test is being run in the SetUp method of the test fixture. This will ensure that each test, no matter the order its run, will have a clean default state upon which to make its assertions.
If a tests needs to make changes to result values or how a mock will behave with a given set of parameters it can modify those dependencies freely without worrying of breaking some future tests since the default state will be reset each time before each test is run.
In this example we have the following classes and interfaces:
The following code example will use these technologies:
Database. This is the relational, key value, or some other data store where our application permanently stores its data. We really do not want to include it in our tests. It will slow them down, we need to insert and clean up dummy data. It is a lot of work for which we may not have enough resources.
In our case in the database we have the following table:
The Account table is used for storing data about our IAccount entity which is going to be used all during this example.
IAccountDataService and AccountDataService. The IAccountDataService is the interface we call upon in the rest of the application to store and read data about an IAccount entity from the permanent data storage. The AccountDataService is the concrete realization of the interface that actually gets to go to the database and retrieve the data requested by someone else. We use and interface here in conjunction with an Inversion of Control container in order to be able to mock the AccountDataService class in unit test for those classes of which this class is a dependency since we really do not want to test the AccountDataService class nor do we want to hit the database.
The IAccountDataService would be placed in a separate library, whose only task would be the direct communication with the database. The library will make use of primary types as parameters (integers, string , booleans etc. ) and DataTable as result types in order to abstract the data access layers from the domain library of the application. This will give us several benefits. For one we can safely replace the permanent data source for something else, another database or web service and our contract would not change since would still returns DataTable and receive primary types as values. It also leaves the data access layer blissfully ignorant about our domain layer and the business logic it implements. Our data access layer does one thing and one thing only it reads and saves data as requested without thinking it at all.
The AccountDataService class has the following methods:
The Get(int):DataTable methods has the task of going to the database and retrieving the data needed to fill a specific entity based on its id.
IAccount and Account. IAccount is our interface for out business entity Account. It may or may not have some business logic in it. As our system will grow it will surely start to have some logic so it is good to prepare it for being mocked in tests.
The Save(int, float, string):DataTable method has the task of inserting or updating a single Account record in the database. The save method will be determined by the id parameter of the method. If its values is zero it will be an insert operation, if its something else it will be and update operation. In case of an insert the method will retrieve also the new id of the record and return it in the DataTable containing the newly updated record.
IAccountRepository and AccountRepository. This is our domain repository class for the IAccount entity. It handles all logic related to the reading and saving of a IAccount entity. This is also our class being tested. It has two dependencies. One is the IAccountDataService from which it gets the raw data it needs to make IAccount objects, and the other is the IAccount entity which is passed as argument to it or is returned by it. Both dependencies come to the AccountRepository object through the Inversion of Control container.
The IAccountRepository is located in the same layer as the IAccount entity. Given its dependency to the IAccoundDataService object it doesn't have to worry about the specifics of how the IAccount entity is saved or retrieved. Its only goal is to worry about the business logic of saving and retrieving the IAccount entity. In case of a future development where the IAccount entity will store and retrieve a part of its data structure from somewhere else, e.g. a file saved to the disk it will be the job of the IAccountRepository to coordinate those sets of operations also.
Another good thing of this structure is that the IAccountRepository object is the only interaction point between the data layer of the application and the domain layer. Which means that the entire domain layer is oblivious how the IAccount object is stored. This will enable us during integration testing to switch the permanent storage to another one, if possibly, memory based like Sqlite or just plain objects.
The AccountRepository class looks like this:
The IAccountDataService is a private field of the class. It makes senses since it is used by the most of the methods contained in the AccountRepository class. The specific instance of the IAccountDataService used is instantiated in the constructor of the class using the StructureMap inversion of control container. We are working here with interfaces, so during testing we can and will replace the default instance of the IAccountDataService with a fake one for our testing purposes.
The mapDataRow(Row):IAccount method is used through the class to map a DataRow returned by the IAccountDataService to an IAccount instance.
The AccountRepository class has the following methods:
The Get(int):IAccount method is very simple. It calls to the IAccountDataService instance with an integer parameter and transforms the returned data into a IAccount entity if possible. Since we are requesting a entity with a specific id the IAccoundDataService will not return more then one row. In case the IAccount row wasn't found with the given id the Get method will return a null value for higher layers to handle as appropriate.
The Save(IAccount):void method saves an IAccount instance and then returns a completely filled IAccount instance by reference, e.g. in case of a new IAccount instance the Id property has a value of 0 and is replaced after the Save operation by the newly assigned Id property.
The Save method makes a few checks to make sure everything is all right. First it checks if the IAccount entity is null, in which case it breaks the method execution by throwing an ArgumentNullException. The second check is related to the result returned by the IAccountDataService Save method. If the result returned zero row it throws yet another exception relating to a possible data service error.
IAccount and Account. In this example the IAccount entity servers primarily as a data holder holding data to and from the permanent storage mechanism. As the business domain grows it will also grow with the addition of new fields and domain logic methods. In order to handle this future complexity we used the IAccount interface to facilitate its mocking. Also, to be in sync with the letter of the pattern we are going to mock it also, as it is , besides it being only a collection of three properties. A dependency is a dependency, and the smallest of mistakes can throws us on a wild goose chase in a wrong class searching for bugs that originated somewhere else.
AccountRepositoryTest is our unit-testing fixture for the AccountRepositoryClass. Its basic structure is this:
Before we start writing test we need to identify what our dependencies are and what result they will generally provide for us.
The AccountRepository class has two dependencies as specified above. The first is the IAccountDataService interface and the second is the IAccount entity. We should not worry about it right now. A simple mocked object with automatic property handling will do. The IAccountDataService instance in its both methods it returns a DataTable object, this is our result. Both dependencies and the DataTable result need to be defined in advance.
We have create a mock object for the IAccountDataService and its result a DataTable and a DataRow object. We have made the DataRow object firstRow available as a private field of the test class since there exits a possibility that in some test we may need to change the data returned by the data row, and calling a direct reference is the easiest way of doing it.
Each dependency and its results need to be instantiated to a clean, default state before each test is run thus preventing one test to influence another by modifying the shared dependencies and results. This is done by using the SetUp method of the unit-testing method. This method is execute every time before a test is run.
Now, we are sure that on every test run we are going to have a clean slate in respect to our dependencies and result values. It is important to note the last code block in the SetUp method. This is a StructureMap initialization pattern where we tell the IoC container which instances to bind when a client piece of code requests a specific type, e.g IAccountDataService. This piece of functionality enables us to embed our fake dependencies in our real class without changing its structure and behavior.
Lets us now write some tests and see how this works in real life:
This is a test written using the "Define once, recreate every time" pattern. On the start of the test we define the expected behavior of our dependency fake. We tell it that regardless of the input parameters to return the dataTable result we have defined previously. Then we create an instance of the AccountRepository class and with it we executed its Save method using the accountMock member as a parameter.
Now lets write another test, this time we will check the behavior of the Save method in case there are errors:
In this test I needed a different behavior from the Save method. I knew it was a new clean instance, for which no behavior was defined so I freely defined a new behavior for the fake. The following two assertions were simple enough. First I sent a null as the IAccount parameter in order to check if the Save method correctly threw theArgumentNullException, and then I checked that if the Save method of the IAccountDataSource returned an empty data source if the repository code correctly threw the ApplicationException. This was possible courtesy of the accountDataSourceMock object.
The "Define once, recreate every time" unit testing pattern offers the following benefits:
When unit-testing classes which have a complex dependency matrix we use faking a lot. We create fake objects, mock or stubs, we define their behavior in respect to the needs of the test. We need to do that for every test. Sure when a common pattern emerges, we create helper methods in order to remove duplicate code. Sometimes we need to have a lot of these helper methods, sometimes we need none and are happy to create are dependencies manually inside each test method.
When unit testing objects those outside dependencies are not really important. How they behave is not important. What is important is how our logic of the class being tested behaves based on the conditions we set for it.
The main proposition of the "Define once, recreate every time" unit-test pattern is that when defining each dependency there is some common code which needs to be written only once, and there is also a common behavioral state which also needs to be defined only once.
In this pattern all dependencies and their return values are defined as common members of the test fixture, e.g. testing class. Those dependencies are created each time a new before a test is being run in the SetUp method of the test fixture. This will ensure that each test, no matter the order its run, will have a clean default state upon which to make its assertions.
If a tests needs to make changes to result values or how a mock will behave with a given set of parameters it can modify those dependencies freely without worrying of breaking some future tests since the default state will be reset each time before each test is run.
In this example we have the following classes and interfaces:
- Database
- IAccountDataService
- AccountDataService
- IAccountRepository
- AccountRepository
- IAccount
- Account
- AccountRepositoryTest
The following code example will use these technologies:
Database. This is the relational, key value, or some other data store where our application permanently stores its data. We really do not want to include it in our tests. It will slow them down, we need to insert and clean up dummy data. It is a lot of work for which we may not have enough resources.
In our case in the database we have the following table:
CREATE TABLE Account
(
Id INT PRIMARY KEY NOT NULL,
Name Varchar(256) NOT NULL,
Amount Decimal(10,2) NULL
)
The Account table is used for storing data about our IAccount entity which is going to be used all during this example.
IAccountDataService and AccountDataService. The IAccountDataService is the interface we call upon in the rest of the application to store and read data about an IAccount entity from the permanent data storage. The AccountDataService is the concrete realization of the interface that actually gets to go to the database and retrieve the data requested by someone else. We use and interface here in conjunction with an Inversion of Control container in order to be able to mock the AccountDataService class in unit test for those classes of which this class is a dependency since we really do not want to test the AccountDataService class nor do we want to hit the database.
The IAccountDataService would be placed in a separate library, whose only task would be the direct communication with the database. The library will make use of primary types as parameters (integers, string , booleans etc. ) and DataTable as result types in order to abstract the data access layers from the domain library of the application. This will give us several benefits. For one we can safely replace the permanent data source for something else, another database or web service and our contract would not change since would still returns DataTable and receive primary types as values. It also leaves the data access layer blissfully ignorant about our domain layer and the business logic it implements. Our data access layer does one thing and one thing only it reads and saves data as requested without thinking it at all.
The AccountDataService class has the following methods:
public DataTable Get(int accountId)
{
//.. sql retrieval code here
DataTable result = new DataTable();
result.Columns.Add("Id",typeof(int));
result.Columns.Add("Name",typeof(string));
result.Columns.Add("Amount",typeof(decimal));
//.. get the DataReader
while(reader.Read()) //This will execute only once
{
DataRow row = result.NewRow();
row["Id"]=reader["Id"];
row["Name"]=reader["Name"];
row["Amount"]=reader["Amount"];
result.Rows.Add(row);
}
return result;
}
The Get(int):DataTable methods has the task of going to the database and retrieving the data needed to fill a specific entity based on its id.
IAccount and Account. IAccount is our interface for out business entity Account. It may or may not have some business logic in it. As our system will grow it will surely start to have some logic so it is good to prepare it for being mocked in tests.
public DataTable Save(int id, decimal amount, string name)
{
//.. insert or update logic here
DataTable result = new DataTable();
result.Columns.Add("Id",typeof(int));
result.Columns.Add("Name",typeof(string));
result.Columns.Add("Amount",typeof(decimal));
DataRow row = result.NewRow();
//in case of a insert the intial value is 0,
//but now is the LAST_INSERT_ID of the database
row["Id"] = id ;
row["Name"] = name;
row["Amount"] = amount;
result.Rows.Add(row);
return result;
}
The Save(int, float, string):DataTable method has the task of inserting or updating a single Account record in the database. The save method will be determined by the id parameter of the method. If its values is zero it will be an insert operation, if its something else it will be and update operation. In case of an insert the method will retrieve also the new id of the record and return it in the DataTable containing the newly updated record.
IAccountRepository and AccountRepository. This is our domain repository class for the IAccount entity. It handles all logic related to the reading and saving of a IAccount entity. This is also our class being tested. It has two dependencies. One is the IAccountDataService from which it gets the raw data it needs to make IAccount objects, and the other is the IAccount entity which is passed as argument to it or is returned by it. Both dependencies come to the AccountRepository object through the Inversion of Control container.
The IAccountRepository is located in the same layer as the IAccount entity. Given its dependency to the IAccoundDataService object it doesn't have to worry about the specifics of how the IAccount entity is saved or retrieved. Its only goal is to worry about the business logic of saving and retrieving the IAccount entity. In case of a future development where the IAccount entity will store and retrieve a part of its data structure from somewhere else, e.g. a file saved to the disk it will be the job of the IAccountRepository to coordinate those sets of operations also.
Another good thing of this structure is that the IAccountRepository object is the only interaction point between the data layer of the application and the domain layer. Which means that the entire domain layer is oblivious how the IAccount object is stored. This will enable us during integration testing to switch the permanent storage to another one, if possibly, memory based like Sqlite or just plain objects.
The AccountRepository class looks like this:
public class AccountRepository:IAccountRepository
{
private IAccountDataService accountDataService = null;
public AccountRepository()
{
accountDataService = ObjectFactory.GetInstance();
}
private IAccount mapDataRow(DataRow row)
{
IAccount account = ObjectFactory.Get();
account.Id = row.Field("Id");
account.Name = row.Field("Name");
account.Amount = row.Field("Amount");
return account;
}
}
The IAccountDataService is a private field of the class. It makes senses since it is used by the most of the methods contained in the AccountRepository class. The specific instance of the IAccountDataService used is instantiated in the constructor of the class using the StructureMap inversion of control container. We are working here with interfaces, so during testing we can and will replace the default instance of the IAccountDataService with a fake one for our testing purposes.
The mapDataRow(Row):IAccount method is used through the class to map a DataRow returned by the IAccountDataService to an IAccount instance.
The AccountRepository class has the following methods:
public void Get(int accoundId)
{
DataTable table= accountDataService.Get(accountId);
if (table.Rows.Count == 0 ) return null;
DataRow row = table.Rows[0];
IAccount account = mapDataRow(row);
return account;
}
The Get(int):IAccount method is very simple. It calls to the IAccountDataService instance with an integer parameter and transforms the returned data into a IAccount entity if possible. Since we are requesting a entity with a specific id the IAccoundDataService will not return more then one row. In case the IAccount row wasn't found with the given id the Get method will return a null value for higher layers to handle as appropriate.
public void Save(IAccount account)
{
if (account == null)
{
throw new ArgumentNullException("IAccount cannot be null.");
}
var table = accountDataTable.Save(account.Id,
account.Amount,
account.Name);
if (table.Rows.Count==0)
{
throw new ApplicationException("No data returned by the data service.");
}
DataRow row = table.Rows[0];
account = mapDataRow(row);
}
The Save(IAccount):void method saves an IAccount instance and then returns a completely filled IAccount instance by reference, e.g. in case of a new IAccount instance the Id property has a value of 0 and is replaced after the Save operation by the newly assigned Id property.
The Save method makes a few checks to make sure everything is all right. First it checks if the IAccount entity is null, in which case it breaks the method execution by throwing an ArgumentNullException. The second check is related to the result returned by the IAccountDataService Save method. If the result returned zero row it throws yet another exception relating to a possible data service error.
IAccount and Account. In this example the IAccount entity servers primarily as a data holder holding data to and from the permanent storage mechanism. As the business domain grows it will also grow with the addition of new fields and domain logic methods. In order to handle this future complexity we used the IAccount interface to facilitate its mocking. Also, to be in sync with the letter of the pattern we are going to mock it also, as it is , besides it being only a collection of three properties. A dependency is a dependency, and the smallest of mistakes can throws us on a wild goose chase in a wrong class searching for bugs that originated somewhere else.
AccountRepositoryTest is our unit-testing fixture for the AccountRepositoryClass. Its basic structure is this:
[TestFixture]
public class AccountRepositoryTest
{
...
}
Before we start writing test we need to identify what our dependencies are and what result they will generally provide for us.
The AccountRepository class has two dependencies as specified above. The first is the IAccountDataService interface and the second is the IAccount entity. We should not worry about it right now. A simple mocked object with automatic property handling will do. The IAccountDataService instance in its both methods it returns a DataTable object, this is our result. Both dependencies and the DataTable result need to be defined in advance.
[TestFixture]
public class AccountRepositoryTest
{
private MockaccountDataServiceMock = null;
private DataTable dataTable = null;
private DataRow firstRow = null;
private MockaccountMock = null;
}
We have create a mock object for the IAccountDataService and its result a DataTable and a DataRow object. We have made the DataRow object firstRow available as a private field of the test class since there exits a possibility that in some test we may need to change the data returned by the data row, and calling a direct reference is the easiest way of doing it.
Each dependency and its results need to be instantiated to a clean, default state before each test is run thus preventing one test to influence another by modifying the shared dependencies and results. This is done by using the SetUp method of the unit-testing method. This method is execute every time before a test is run.
[SetUp]
public void SetUp()
{
dataTable = new DataTable();
dataTable.Columns.Add("Id",typeof(int));
dataTable.Columns.Add("Name",typeof(string));
dataTable.Columns.Add("Amount",typeof(decimal));
firstRow = dataTable.NewRow();
firstRow["Id"] = 1;
firstRow["Name"] = "Marko Horvat";
firstRow["Amount"] = 44.00;
accountDataServiceMock = new Mock();
accountMock = new Mock();
accountMock.SetupAllProperties();
accountMock.Object.Id = 1;
accountMock.Object.Name = "Marko Horvat";
accountMock.Object.Amount= 44.00;
ObjectFactory.Initialize(x => {
x.For().Use(accountDataServiceMock.Object);
x.For().Use(accountMock.Object);
});
}
Now, we are sure that on every test run we are going to have a clean slate in respect to our dependencies and result values. It is important to note the last code block in the SetUp method. This is a StructureMap initialization pattern where we tell the IoC container which instances to bind when a client piece of code requests a specific type, e.g IAccountDataService. This piece of functionality enables us to embed our fake dependencies in our real class without changing its structure and behavior.
Lets us now write some tests and see how this works in real life:
public void Save_ProperParameters_AccountSaved()
{
accountDataServiceMock.Setup( x => x.Save(It.IsAny (),
It.IsAny(),
It.IsAny()))
.Returns(dataTable);
var instance = new AccountRepository();
var result = instance.Save(accountMock.Object);
Assert.IsNotNull(result);
Assert.AreEqual(result.Id, accountMock.Object.Id); // 1
}
This is a test written using the "Define once, recreate every time" pattern. On the start of the test we define the expected behavior of our dependency fake. We tell it that regardless of the input parameters to return the dataTable result we have defined previously. Then we create an instance of the AccountRepository class and with it we executed its Save method using the accountMock member as a parameter.
Now lets write another test, this time we will check the behavior of the Save method in case there are errors:
[Test]
public void Save_ErrorRaised_ThrowsExceptions()
{
accountDataServiceMock.Setup(x => x.Save(It.IsAny (),
It.IsAny(),
It.IsAny()))
.Returns(new DataTable());
var instance = new AccountRepository();
Assert.Throws( () => instance.Save(null));
Assert.Throws( () => instance.Save(accountMock.Object));
}
In this test I needed a different behavior from the Save method. I knew it was a new clean instance, for which no behavior was defined so I freely defined a new behavior for the fake. The following two assertions were simple enough. First I sent a null as the IAccount parameter in order to check if the Save method correctly threw theArgumentNullException, and then I checked that if the Save method of the IAccountDataSource returned an empty data source if the repository code correctly threw the ApplicationException. This was possible courtesy of the accountDataSourceMock object.
The "Define once, recreate every time" unit testing pattern offers the following benefits:
- Simplifies unit test writing
- Increases test writing speed
- Reduces the chances of one test modifying the results of another test
15 September 2010
What should I learn next
My wife is a real help to me. Her current contribution is her opinion about my learning schedule for the next six months.
I laid down some choices, what issues are concerning me about each choice and in what order I would like to learn them.
The candidates were:
The winners were WPF 4 and MongoDB. WPF 4 will became my new build, virtual machine startup reading and MongoDB will became my evening exercises technology.
I laid down some choices, what issues are concerning me about each choice and in what order I would like to learn them.
The candidates were:
- Oracle
- MongoDb
- WPF 4
The winners were WPF 4 and MongoDB. WPF 4 will became my new build, virtual machine startup reading and MongoDB will became my evening exercises technology.
Oznake:
education
13 September 2010
Lets ignore them, will ya!
Once upon a time, on a project far away a young group of engineers dutifully wrote unit tests for almost everything on the project. The project also had some really tricky integration points with other systems. And those integration points were faulty, and those tests broke. So out team of heroes dutifully applied the Ignore tag to those tests covering those integration points which were faulty until they were fixed by their respective teams.
And so the gates of Ignorance were opened, and upon the project a beast was unleashed and its name was laziness since every set of tests which was difficult to fix or it required a fair amount of time to fix the defects it exposed was dutifully sent to the forges of Ignorance by the Ignore attribute.
A man arose from the ranks. He thought him self a leader, a thinker and said no more in his head. Nobody heard him, yet, for he was wise in marking his words right and waiting for the right moment to utter those life changing words.
And so we waited, to see what will become of the project and the stalwart team of young engineers doing their best to test what was easy, and to forget what was hard.
And so the gates of Ignorance were opened, and upon the project a beast was unleashed and its name was laziness since every set of tests which was difficult to fix or it required a fair amount of time to fix the defects it exposed was dutifully sent to the forges of Ignorance by the Ignore attribute.
A man arose from the ranks. He thought him self a leader, a thinker and said no more in his head. Nobody heard him, yet, for he was wise in marking his words right and waiting for the right moment to utter those life changing words.
And so we waited, to see what will become of the project and the stalwart team of young engineers doing their best to test what was easy, and to forget what was hard.
Oznake:
.NET,
nunit,
Unit testing
12 September 2010
Nine to five
It took me a while to make my self see and surrender to the fact that not all people I work, I've worked and will work with me in the future, have accepted The Life, or the way of a software engineer or craftsman.
Oh, how I've grown wiser and older. I just might grow a beard and be a guru of some sorts. Certainly there is a niche I can squeeze in a pretend to know what I'm talking about.
But alas, I didn't grow wiser just battered down by the entropy that is the , oh so typical , human philosophy of working from nine to five and then at five o' one forgetting that work even exists.
Well I can understand that. Work is work, and it isn't the whole life. But for the way of a software engineer or craftsman isn't just work , the daily grudge of projects, meetings, coding and testing the constant battle of will and code and the requirements that just won't fit into the application mold. It is just not.
For me it is something different, something more. A thing to be proud of , something to leave for posterity. Is the way of living where you read, learn, exercise your self and improve your self. Year after, year continuously. And the work is the place where you apply your skills, your learning, your spirit into something tangible, something you can be proud of, an achievement.
Am I , or people like me, better then the rest. I think not. We are just different. I often found that people with the nine to five mentality are predictable, they approach each problem in a similar fashion, they apply the same solutions every time, day after day, application after application. On the other hand, the same errors are repeated, the same problems occur nothing is improved until pressure is applied from the outside, or if not they succumb to the technology wave, left behind with outdated knowledge and if something doesn't come by, a new project or a new job where the can learn new skills in a nine to five way they are really frakked up.
This is what scares me the most, as a developer, to let my self loose, to relax and to in a matter of years outdated, jobless, and skill less.
We work in teams. We seldom do any work alone. Teams can be organized differently, they can work differently. But one constant remains often, in teams there are some people that want to improve them self and the the work they are doing and those who just can't see the need to bother to do so.
For this was an enormous amount of stress, battling such teammates day after day until it downed me. I can't change them. I can't force them. I just can behave with my code, my tasks the way I think is right and if they'll follow me the batter or if not I will refactor their code or leave it as is.
Oh, how I've grown wiser and older. I just might grow a beard and be a guru of some sorts. Certainly there is a niche I can squeeze in a pretend to know what I'm talking about.
But alas, I didn't grow wiser just battered down by the entropy that is the , oh so typical , human philosophy of working from nine to five and then at five o' one forgetting that work even exists.
Well I can understand that. Work is work, and it isn't the whole life. But for the way of a software engineer or craftsman isn't just work , the daily grudge of projects, meetings, coding and testing the constant battle of will and code and the requirements that just won't fit into the application mold. It is just not.
For me it is something different, something more. A thing to be proud of , something to leave for posterity. Is the way of living where you read, learn, exercise your self and improve your self. Year after, year continuously. And the work is the place where you apply your skills, your learning, your spirit into something tangible, something you can be proud of, an achievement.
Am I , or people like me, better then the rest. I think not. We are just different. I often found that people with the nine to five mentality are predictable, they approach each problem in a similar fashion, they apply the same solutions every time, day after day, application after application. On the other hand, the same errors are repeated, the same problems occur nothing is improved until pressure is applied from the outside, or if not they succumb to the technology wave, left behind with outdated knowledge and if something doesn't come by, a new project or a new job where the can learn new skills in a nine to five way they are really frakked up.
This is what scares me the most, as a developer, to let my self loose, to relax and to in a matter of years outdated, jobless, and skill less.
We work in teams. We seldom do any work alone. Teams can be organized differently, they can work differently. But one constant remains often, in teams there are some people that want to improve them self and the the work they are doing and those who just can't see the need to bother to do so.
For this was an enormous amount of stress, battling such teammates day after day until it downed me. I can't change them. I can't force them. I just can behave with my code, my tasks the way I think is right and if they'll follow me the batter or if not I will refactor their code or leave it as is.
10 September 2010
To fake or not to fake
To fake , or not to fake that is the problem now. This is something I just realized after writting around two hundred tests that rely on completely faked dependencies, and around seventy which do not fake nothing. Those non-faking unit tests are those written for the lowest layer of the applicattion, the data access code which tests how my data retrieval code works with a real database with only the data faked. Those tests sometime rely on each other since sometimes one stored procedure or view is used by multiple different sources. And if I change one multiple tests will fall indicating to me or my team where we need to apply out changes also.
But on a faked enviroment, where all dependencies are faked if we change the logic in one dependency and write tests that pass for it we must manually go and look through the code and to find all the places where that dependency is used in order to update it to the newest state of the application. Why? If I didn't change the structure of the dependency or the type of results it returns the tests that use a fake of the dependency will pass since those logic changes will not automatically propagate to those fakes (mocks or stubs it is irrelevant which in this case).
No that is why I push for functional and acceptance tests in order to test the complete stack from ground up without mocking, but still those tests are often left aside since people who have written unit tests have decided that they are unnecessary duplication or effort, or worse botch them in such a was that those tests do not return any meaningful data to us.
But on a faked enviroment, where all dependencies are faked if we change the logic in one dependency and write tests that pass for it we must manually go and look through the code and to find all the places where that dependency is used in order to update it to the newest state of the application. Why? If I didn't change the structure of the dependency or the type of results it returns the tests that use a fake of the dependency will pass since those logic changes will not automatically propagate to those fakes (mocks or stubs it is irrelevant which in this case).
No that is why I push for functional and acceptance tests in order to test the complete stack from ground up without mocking, but still those tests are often left aside since people who have written unit tests have decided that they are unnecessary duplication or effort, or worse botch them in such a was that those tests do not return any meaningful data to us.
Oznake:
Faking,
Unit testing
08 September 2010
How much granularity is enough?
I worked sometime ago on a small/medium sized ERP project. Once again it was a ASP.NET web application.
In order to write a feature the following steps must had to be taken:
When looked from a theoretical aspect each step made sense. A clear separation of concerns, each object doing its small thing etc. But during the implementation I just often found my self wondering Why am I doing this? Each object has only a small variation from the object bellow. Isn't this to much granular?.
It sure made writing tests easier, since the logic in each object wasn't very complicated so the corresponding tests were easier to write and were written much faster, especially on upper layers where I made extensive use of the Moq mocking framework.
In order to write a feature the following steps must had to be taken:
- Write a stored procedure, or two
- For each procedure write a method in the related data service in the data access layer of the application
- For each method in the underlying data access service write one or more methods in one or more repository objects in the logic layer.
- Write one or more entities, value objects and aggregates related to the procedure written.
- For each function write a method in the appropriate object service on top of the logic layer.
- On the front end write a service facade for collecting errors and results from the logic service, once again is a one to one mapping (I used the ObjectDataSource control extensively in this project and we had a centralized message collecting system).
- Write the functionality on the screen.
When looked from a theoretical aspect each step made sense. A clear separation of concerns, each object doing its small thing etc. But during the implementation I just often found my self wondering Why am I doing this? Each object has only a small variation from the object bellow. Isn't this to much granular?.
It sure made writing tests easier, since the logic in each object wasn't very complicated so the corresponding tests were easier to write and were written much faster, especially on upper layers where I made extensive use of the Moq mocking framework.
Oznake:
arhitecture
07 September 2010
Just unit test?
I just realized something today. Something deep, and profound and totally astonishing . Well, for me anyway. I realized that maybe, just maybe doing unit tests on project is enough. On most projects I have an influence on I strive to have functional and integration tests besides regular unit test. I just feel is best to cover each layer of the application in one fell swoop with functional tests or acceptance test (it depends really how you do them) with a good coverage of unit test for each object separately.
Today I've done a lot of unit tests. I worked late, and I've done a lot of coding. For class I've done I wrote unit test. And with those tests I covered a lot of functionality of the application. When I reached the user interface there wasn't much to test, everything worked fine since I got the majority of the defects with unit tests on the lower layers.
It seems strange to me since we do tests in complete isolation from each other, so no outside dependencies between tests are allowed. Everything is mocked. But with a real fine granularity of objects for a specific functionality it is possible in my opinion to just have unit tests and cover the majority of the expected functionality of the application.
Today I've done a lot of unit tests. I worked late, and I've done a lot of coding. For class I've done I wrote unit test. And with those tests I covered a lot of functionality of the application. When I reached the user interface there wasn't much to test, everything worked fine since I got the majority of the defects with unit tests on the lower layers.
It seems strange to me since we do tests in complete isolation from each other, so no outside dependencies between tests are allowed. Everything is mocked. But with a real fine granularity of objects for a specific functionality it is possible in my opinion to just have unit tests and cover the majority of the expected functionality of the application.
03 September 2010
How to cranck unit tests under pressure, and not feeling dirty at the same time
It's called doing the right thing.
Well thats what I tell my self it is. When I read "Extreme programming Explained" by Kent Beck I read about a story of his about a project where he introduced extreme programming as a development process. The project went well until the deadline got really close and wished he could just throw XP from the window, hack the project together and completed the project in time to collect a big, fat, juicy bonus. He addmitted he panicked, and then calmed him self down when a colleague told him that nothing really changed, that they should plan for the last two weeks of the project as it were an ordinary iteration, and execute it as such with unit testing and everything.
Now I was in a pinch some time ago. Not something unusual, per self, it seems there is not enough time to ever do a project. The project was then involved was in development for some time, and the deadline of the clients patience got really closer as each week passed.
It was a good project, I've architected it and technically oversaw the development for much of its life time as I was in parallel involved in other enterprises. It got a stable architecture, which followed closely my plan, it got unit tests, inversion of control, mocking ,functional tests and a set of Selenium based acceptance tests.
I event wrote a set of QUnit (a javascript unit testing framework) test for the Javascript classes we used on the project.
The problem was that the we got a week left and still a lot of stuff to do if wanted to do it right, before the final client presentation. Like writing tests, logging code etc.
The pressure started to mount, just finish those damned screens everybody yelled (not really but my minds plays such beautiful tricks on me). Just get it done, write those pesky tests later.
The problem was I was feeling really good about the projects, the tests were written quickly and were really useful to ferret defects and I really didn't want to abandon all those three hundred plus tests to entropy and mocking disregard.
What I decided to do is to change my unit testing strategy:
It kinda worked. I cranked a lot of more code this way and found a lot of defects. I wouldn't suggest it as a unit testing strategy for everyday situations but it kinda works when under pressure.
Well thats what I tell my self it is. When I read "Extreme programming Explained" by Kent Beck I read about a story of his about a project where he introduced extreme programming as a development process. The project went well until the deadline got really close and wished he could just throw XP from the window, hack the project together and completed the project in time to collect a big, fat, juicy bonus. He addmitted he panicked, and then calmed him self down when a colleague told him that nothing really changed, that they should plan for the last two weeks of the project as it were an ordinary iteration, and execute it as such with unit testing and everything.
Now I was in a pinch some time ago. Not something unusual, per self, it seems there is not enough time to ever do a project. The project was then involved was in development for some time, and the deadline of the clients patience got really closer as each week passed.
It was a good project, I've architected it and technically oversaw the development for much of its life time as I was in parallel involved in other enterprises. It got a stable architecture, which followed closely my plan, it got unit tests, inversion of control, mocking ,functional tests and a set of Selenium based acceptance tests.
I event wrote a set of QUnit (a javascript unit testing framework) test for the Javascript classes we used on the project.
The problem was that the we got a week left and still a lot of stuff to do if wanted to do it right, before the final client presentation. Like writing tests, logging code etc.
The pressure started to mount, just finish those damned screens everybody yelled (not really but my minds plays such beautiful tricks on me). Just get it done, write those pesky tests later.
The problem was I was feeling really good about the projects, the tests were written quickly and were really useful to ferret defects and I really didn't want to abandon all those three hundred plus tests to entropy and mocking disregard.
What I decided to do is to change my unit testing strategy:
- Test only logic heavy code. If a method has an if, switch or any other control structure I would test it in respect to the general expected behavior which could result from those control structures.
- Change focus from data to processes. I left trying to set replicas of real world data, and instead used generic values like "1" for ints and "Any" for strings. This left me with more time and didn't stress my mind to try to figure out real, representative , data sets.
- Tell your self is good to copy paste (for now). I had tests which were five to seven lines long each. They all had 30%-40% of the same code base. What I originally do I refactor out the common code in a private method and reduce my overall tests size. The downside of this it takes time do do it. Time which I really didn't have. So I copy pasted.
- In a object stack which covers a specific functionality (e.g. GetAllAccounts) do not retest the same functionality on each step, but instead focus really closely to the task of each object in the stack. For example I would focus really hard on querying and inserting data from the permanent storage in the Data Layer of the application, and focus on data transformation and repository logic in the middle tier of the application.
It kinda worked. I cranked a lot of more code this way and found a lot of defects. I wouldn't suggest it as a unit testing strategy for everyday situations but it kinda works when under pressure.
01 September 2010
Oh, my learning muse
I didn't write in four months now. It didn't seem to matter, nothing did which was related to my work. What happened to me?
Well, I've been pushing my self for the last three years very hard. Learning, working and applying my self in order to grow, learn and advance as a software engineer. And then I crashed, emotionally and physically. I become cranky , tired and frustrated.
I started then working from home, so I didn't have to drive for two hours a day on really low grade roads. I saw more of my family, and I was more rested.
One thing led to another, I started to shift my priorities to my son and wife. I started spending more time with them, going out to play by the sea, watching movies reading books, going out. Just living my life.
What was not right, was the nagging feeling that something was not right. A sick rotten feeling that I was leaving out something vital and important to me. My learning and education. My personal growth as a professional.
It got to the point that I felt my brain rot from not use. And I didn't like it. So I started learning again, "Patterns of Enterprise Application Architecture" by Martin Fowler, and "WPF Unleashed 4" by Adam Nathan. The former as my regular reading and the latter as my computer time in the evening and weekends reading.
I feel more right now. I guess. I don't spend as much time at the computer cranking code and learning new stuff as I would like.
Every time I can sit at my machine and learn , it seems it is ten in the evening and I'm to tired, my head hurts and I just want to unwind. It is really hard to keep up.
Well, I've been pushing my self for the last three years very hard. Learning, working and applying my self in order to grow, learn and advance as a software engineer. And then I crashed, emotionally and physically. I become cranky , tired and frustrated.
I started then working from home, so I didn't have to drive for two hours a day on really low grade roads. I saw more of my family, and I was more rested.
One thing led to another, I started to shift my priorities to my son and wife. I started spending more time with them, going out to play by the sea, watching movies reading books, going out. Just living my life.
What was not right, was the nagging feeling that something was not right. A sick rotten feeling that I was leaving out something vital and important to me. My learning and education. My personal growth as a professional.
It got to the point that I felt my brain rot from not use. And I didn't like it. So I started learning again, "Patterns of Enterprise Application Architecture" by Martin Fowler, and "WPF Unleashed 4" by Adam Nathan. The former as my regular reading and the latter as my computer time in the evening and weekends reading.
I feel more right now. I guess. I don't spend as much time at the computer cranking code and learning new stuff as I would like.
Every time I can sit at my machine and learn , it seems it is ten in the evening and I'm to tired, my head hurts and I just want to unwind. It is really hard to keep up.
Subscribe to:
Posts (Atom)