Test Driven Development

From bibbleWiki
Jump to navigation Jump to search

Introduction

Costs

The cost of software according to this course was Tests are split into three categories

  • Does what was asked for
  • Responds appropriately to bad input
  • Acceptable Performance

Red Green Refactor

Start by writing tests with no code, write until test pass, refactor code. This is an iterative approach.

Benefits

  • Requirements are verified by the tests
  • Regression issues raised early
  • Costs of maintenance is lowered
  • Design first, when writing the tests first we are designing what they want
  • Reduces over engineering
  • Easy to know where you are in the project

Different Types of Testing

Types of Testing

  • Unit Testing
  • Functional Testing (UI/End-to-End)
  • Integrating Testing
  • User Acceptance Testing

Testing Approaches

  • Black Box testing (testing the interface)
  • White Box testing (testing internal aspects)

Tools

Some well known tools are

  • Selenium
  • Watir
  • VS Coded UI
  • Test Studio (Telerik)
  • Silk Test (Micro Focus)

Terminology

  • Test
  • Test Suite (Group of tests)
  • Before/After hooks to set up and tear down
  • Assert, eg. isTrue, isNull, areEqual
  • Test Execution
  • Test Runner (async/sync)

Example Fizz Buzz

Requirements

This has the following requirements Given a positive number

  • Divisible by 3 => "Fizz"
  • Divisible by 5 => "Buzz"
  • Divisible by 3 & 5 => "Fizz Buzz"
  • Otherwise => Number

Step 1

Create initial test

        private FizzBuzzService _fizzBuzzService;

        public FizzBuzzTests() {
            _fizzBuzzService = new FizzBuzzService();
        }

        [TestMethod]
        public void ShouldPrintNumber() {
            Assert.AreEqual("1", _fizzBuzzService.Print(1));
        }

Step 2

So lets build out tests up as we go until we get to.

...
        [TestMethod]
        public void ShouldPrintFizz()
        {
            Assert.AreEqual("Fizz", _fizzBuzz.Print(3));
        }

        [TestMethod]
        public void ShouldPrintBuzz()
        {
            Assert.AreEqual("Buzz", _fizzBuzz.Print(5));
            Assert.AreEqual("Buzz", _fizzBuzz.Print(10));
        }

        [TestMethod]
        public void ShouldPrintFizzBuzz()
        {
            Assert.AreEqual("FizzBuzz", _fizzBuzz.Print(15));
        }
...

Techniques

Dependency Injection

This is used in Frameworks all the time. The problem is that if we did not create a service and inject it but instead created in the class we are testing, it would be far harder to get the service to be in the correct state for the test. But if the service is passed in we could easily mock the state to do the test.

public class Greeter {
   private NameService nameService;
   public Greeter() {
     this.nameService = new NamService()
   }

   public string SayHello() {
      return $"Hello, {this.nameService.GetName()}";
   }
}