开发者

Applying Test Driven Development to a tightly coupled architecture

开发者 https://www.devze.com 2022-12-24 02:22 出处:网络
I\'ve recently been studying TDD, attended a conference and have dabbled in few tests and already I\'m 100% sold, I absolutely love it TDD.

I've recently been studying TDD, attended a conference and have dabbled in few tests and already I'm 100% sold, I absolutely love it TDD.

As a result I've raised this with my seniors and they are prepared to give it a chance, so they have tasked me with coming up with a way to implement TDD in the development of our enterprise product.

The problem is our system has evolved since the days of VB6 to .NET and implements a lot of legacy technology and some far from best practice development techniques i.e. a lot of business logic in the ASP.NET code behind and client script. The largest problem however is how our classes are tightly coupled with database access; properties, methods, constructors - usually has some database access in some form or another.

We use an in-house data access code generator tool that creates sqlDataAdapters that gives us all the database access we could ever want, which helps us develop extremely quickly, however, classes in our business layer are very tightly coupled to this data layer - we aren't even close to implementing some form of repository design. This and the issues above have created me all sorts of problems.

I have tried to develop some unit tests for some existing classes I've already written but the tests take A LOT longer to run since db access is required, not to mention since we use the MS Enterprise Caching framework I am forced to fake a httpcontext for my tests to run successfully which isn't practical. Also, I can't see how to u开发者_如何学运维se TDD to drive the design of any new classes I write since they have to be so tightly coupled to the database ... help!

Because of the architecture of the system it appears I can't implement TDD without some real hack which in my eyes just defeats the aim of TDD and the huge benefits that come with.

Does anyone have any suggestions how I could implement TDD with the constraints I'm bound to? Or do I need to push the repository design pattern down my seniors throats and tell them we either change our architecture/development methodology or forget about TDD altogether? :)

Thanks


Just to clarify, Test driven development and unit testing are not the same thing.

  • TDD = Write your tests before your code.
  • Unit Testing = Writing tests that confirm a small unit of code works.
  • Integration Testing = Writing tests that confirm blocks of code work together.

TDD, by definition, can't be done on existing code. You've already developed the code, so you aren't going to develop it again. TDD means you first write a failing test, then you write just enough code to pass the test. You've already written the code, so you can't do TDD.

You can write unit tests for existing code but this isn't the same as doing TDD.

The tests you have described (accessing the database etc) are technically integration tests. Integration tests do usually take ages to run. A true unit test would purely test your DA layer code without actually accessing the database. True unit testing requires interfaces to test against so you can isolate units from the surrounding units.

It's very hard to properly unit test existing code, unless it's been well designed with interfaces and abstraction in mind.

I know I'm being slightly picky with terminology here, but it's important when it comes to what approach you can take. My advice would be that with existing code that isn't well abstracted you should gradually build up a suite of automated integration tests. When you come to write something new (Which may not be a whole project, it may just be a new part to the existing app), consider approaching it in a TDD style. To do this you will find that you need to write some interfaces and abstractions to allow you to do TDD on your new code without triggering too much of the existing code. You will then be able to write some more integration tests that test your new code working with the old code.

To cut it short - don't try and change methodology for existing code. Just do new code better.


Nitpick: you can't do Test-Driven Design on existing code, but I do realize that you wish to use TDD against new functionality you implement on the existing code base.

The best thing you can do is to gradually introduce seams into the code base, shielding you from the tightly coupled code already in existence.

The book Working Effectively with Legacy Code contains much good advice on how to turn a legacy application into a testable application.


I think the mere fact that you are using ASP.NET Web Forms your road to TDD will be challenged. It's just a nightmare to mock the Session/ViewState/HTTPContext in Web Forms so test-driven is almost a hindrance. There is of course the ASP.NET MVC alternative, but you're way down the road already it seems. Another promising option for the Web Forms paradigm is ASP.NET Web Forms MVP, but that project is really not fully mature yet. I'm moving everything I can to MVC; the other option for TDD with Web Forms, Selenium, isn't really TDD as it should be.


For adding tests to your existing code, you might check out Working Effectively With Legacy Code. "Legacy code" is defined as code that does not have tests in it.

0

精彩评论

暂无评论...
验证码 换一张
取 消