XPCShell test output changes

13 June, 2013 § Leave a comment

Those of you using XPCShell tests may notice some slightly improved output from the test macros that landed recently on mozilla-central.

Previously, if you called do_check_null(null), you would get an output that was similar to:

[TEST-PASS] null == null

However, if you tried do_check_null("null"), you would get an output that was similar to:

[TEST-FAIL] null == null

This isn’t very helpful, and I ran into this exact issue while working on some code that uses observers. Since the data is passed as JSON, when JSON.stringify(null) is called the result is “null”. The test runner showing null == null as a failure isn’t too helpful :-P

With this recent change, all string arguments will be adorned with double-quotes.

This means that calling do_check_null("null") will now output:

[TEST-FAIL] "null" == null

The same change was made for all of the other do_check_* and do_print macros.

Unit testing code behinds in ASP.Net Web Forms

13 June, 2010 § 5 Comments

Have you ever inherited an ASP.Net website with waaaaaaay too much logic in the code behinds?

A while back I came up with a solution to solving this problem. I don’t have a name for it, but if you do, please leave a comment at the end of this post.

The problem that I was trying to solve is that I wanted to make a new page and implement it using Test Driven Development. The hard part was that there was a lot of code that basically dealt with the visual aspect and interaction of the page but not much with the data model. I needed to find a way to write tests around this code, as the data model code already had a framework for writing tests.

Here is an example of the before-case:

public class CodeBehind : System.Web.UI.Page {
   protected void btnFindUser_Click(Object obj,  EventArgs e) {
      if (Page.IsValid) {
         var dbConnection = new DatabaseConnection();
         var users = dbConnection.GetUsers( txtQuery.Text );
         if ( !users.empty() ) {
            dataTable.Bind(  users );
         }
      }
   }
}

What I came up with was an introduction of a “controller” class that lived outside of the ASP.Net Web Forms project. Here is an example of the after-case:

// CodeBehind.aspx.cs
public class CodeBehind : System.Web.UI.Page {
   protected void btnFindUser_Click(Object obj,  EventArgs e) {
      controller.FindUser( Page.IsValid, txtQuery.Text, dataTable );
   }
}

// CodeBehindController.cs
public class CodeBehindController {
   public void FindUser( bool pageIsValid, string query, DataTable dataTable ) {
      if ( pageIsValid ) {
         var dbConnection = new DatabaseConnection();
         var users = dbConnection.GetUsers( query );
         if ( !users.empty() ) {
            dataTable.Bind( users );
         }
      }
   }
}

// CodeBehindControllerTests.cs
public class CodeBehindControllerTests {
   public void FindUser_WithNoUsersFound_DataTableIsEmpty() {
      DataTable table = new DataTable();
      CodeBehindController controller = new CodeBehindController();

      controller.FindUser( true, "ImpossibleUserToFind", table );

      Assert.IsTrue( table.empty() );
   }
}

With that, I can now mock out the DatabaseConnection and the DataTable and I’m good to go. By passing in Page.IsValid instead of the whole Page object, I’m able to provide types that are easier to instantiate and I also now have code with less dependencies.

Getting this to work is actually very simple. Just introduce another class and put all of your logic in that class. There shouldn’t be a single conditional in your *.aspx.cs page. As long as you follow this pattern, it should be pretty easy to TDD your next ASP.Net Web Forms page.

Any questions? Leave a comment and I’d be glad to help.

Finished Reading Clean Code

20 December, 2009 § 2 Comments

Today I finished reading Clean Code by Robert Martin aka Uncle Bob. I found out about the book from some coworkers during our weekly programming-discussion meetings. The book claims to leave its readers understanding:

  • How to tell the difference between good and bad code
  • How to write good code and how to transform bad code into good code
  • How to create good names, good functions, good objects, and good classes
  • How to format code for maximum readability
  • How to implement complete error handling without obscuring code logic
  • How to unit test and practice test-driven development

Part 1: Principles, Practices, and Patterns

I really liked part one of the book. The principles, practices, and patterns are well thought out and provide a style of programming that is,¬†unfortunately, rarely seen. Since reading this part, I’ve been writing smaller functions (about 4-5 lines at max) and have seen a payoff in the amount of reusability and readability. Chapters 1-7 read quickly, are informative, and are really great pieces to read.

Part 2: Case Studies

The pace of the book really drops off after chapter 7, and each subsequent chapter I lost more of that urge to pick up the book and continue reading. The final nail in the coffin that actually put me to sleep once was the Case Studies part (chapters 14-16). The example of the Args module was too large and my internal-brain compiler just couldn’t handle JITting three pages of code at once. I pushed through and read this whole part, but I wouldn’t recommend you doing the same.

Part 3: Code Smells

Part three is one chapter long and focuses on Code Smells. Code Smells are patterns in code that when seen give a bad taste in your mouth. They are implementations that shout that they could have been done better. The longer the code smells, the worse it gets, until finally the abomination that once started out as a faint odor now is the muskiness in the room that scares off developers from maintaining the module. This chapter is important to get familiar with. It might not be too useful to memorize the different smells, but knowing which ones exist is good enough, because you can always come back to this chapter to see how the code can be refactored.

Unit Testing

The last item I wanted to cover was unit testing. While the book mentions unit testing a lot, and devotes a chapter towards it, I don’t feel like developers will walk away from this book with an understanding of unit tests and test-driven development. Any developer looking for further understanding on unit tests should pick up a book that is devoted to the practice, since there is just far too much to cover in one chapter. I would recommend reading Test Driven Development: By Example.

Python Unit Tests

26 April, 2009 § Leave a comment

Yesterday, I wrote my first project from scratch in Python using TDD and it was a pleasure.

The integration of unittests in the Python language took away many headaches that come from setting up an environment in other languages such as C++ or C#. To get started, just import unittest. The next step to configuring is to call unittest.main() from your main loop. That’s all the configuration necessary to start writing unit tests in Python.

When I was writing the tests, I followed Kent Beck’s recommendation to make a to-do list and I really liked how it turned out. The first thing I did was read through some of the documentation and write down different tests I could write. After writing them down, I picked the easiest one out of the list. Moving through the list this way made the work less stressful, not to mention the whole part about having the tests check to make sure everything works.

When I chose an item from the list I made it bold, and when I had finished it I put a strike through it. If anything came up while working on that item, I added it to the list.

The only hiccup that I ran into while working on it was IDLE’s improper handling of the unittest’s exit. When the tests are finished, they throw some type of exception. Apparently this isn’t a problem with other runtimes, so the way I fixed it was surrounding the unittest.main() with a try: and except:. Nothing is hidden from the developer if a unit test fails.

My notes on “Test Driven Development: By Example” by Kent Beck

24 April, 2009 § 2 Comments

These are my unordered notes that I took while reading Test Driven Development: By Example, by Kent Beck. I took a different route with these notes as opposed to my previous notes on Effective C++. If you read both, let me know which way is more informative.

Test Driven Development: By Example is a book that teaches how you can test the software that you write proactively. Ron Jeffries said that the goal of TDD is “clean code that works.” When you write your code TDD, the tests tell you that it works, and since one of the steps of TDD is to refactor, you should have clean code that lacks duplication.

The book is set up in three distinct parts. The first part takes you through a simple currency exchange example and shows how you could write unit tests, starting with something that is achievable and building up from there. The second part explains how xUnit works, and interestingly, Kent shows how by having you write your own xUnit library in Python using TDD. Writing the testing library using tests? Yes, and it’s really cool how he does it. Part three covers many TDD design patterns and development processes. Here are the notes that I took while reading the book:

  • While coding, you should make a to-do list. Tackle what is easy and if you notice anything else to do, just add it to the to-do list. You can come back to the list later for the next item to work on. This way, you won’t forget anything that comes to mind and can stay on track. Your to-do list can also be a list of tests that need to be made. These tests will then lead development of the feature.
  • With TDD, you can test an experiment and back it out. You know right away if it will work or not.
  • Three strategies for a green bar:
    • Fake It – Return a constant
    • Obvious Implementation – If the implementation is obvious, go ahead and implement it
    • Triangulation – Two tests that both cover the same code to get rid of faking it. If you are having trouble figuring out how to implement the code, triangulation can help you out.
  • Obvious implementation is a fast way to implement what you know. Triangulation and Faking It are baby steps compared to Obvious Implementation.
  • Value objects: once initialized, they don’t change. Anything that changes them returns a copy with the new value. Value objects must also implement operators like equals though.
  • Impostor pattern: Objects that have the same external protocol but don’t behave the same way.
  • Chapter 14 talks about creating a pair class. Isn’t there something like¬† std::pair in Java?
  • Bill Wake says your tests should follow the three A’s: { Arrange, Act, Assert }
  • In the same spirit of test first, you should write assertions first and then figure out what test code is needed.
  • Don’t obscure the test results, use Evident Data to show what’s expected. This means that if a test is checking that a result is 2/3 the input, you shouldn’t precalculate the expected output. Instead, you should just show that the output is expected to be 2/3 * input.
  • If a test needs to work on many values, start with just one, then refactor to many.
  • You should end up with the same number of lines of test code as model code with TDD. This doubles the amount of code that you write, but it should limit the amount of regression that occurs, and give you an idea right away if your code works as intended.
  • The number of changes per refactoring should have a fat tail, this is also called a Leptokurtotic profile.

Notable quotes:

  • On xUnit, “Never in the annals of software engineering was so much owed by so many to so few lines of code” – Martin Fowler
  • On TDD: “The goal is clean code that works” – Ron Jeffries

Where Am I?

You are currently browsing entries tagged with tdd at JAWS.

Follow

Get every new post delivered to your Inbox.

Join 100 other followers