Practical unit testing tips

Preview:

DESCRIPTION

Practical unit testing tips from

Citation preview

UNIT TESTINGPractical Tips

In the beginning• First testing experience

Why Unit Testing?• Instead of starting by Testing Manually, you start by

testing programmatically.

• You test the code once…• … and then continuously afterwards.

• Guards against others breaking your code.• Guards against regression errors.• Refactoring Ruthlessly• Peace of Mind

Types of Testing – All Important• Functional Testing (manual)

• Integration Testing (automated)• (Dosens)• Slow

• Unit Testing (automated)• (Hundreds)• Localize Failures• Fast• Dynamic Language Debuggers

UI Layer

Logic Layer

Data Layer

Person View

Person Controller

Person Model

Security Manager

Test-First of Test-After?• The difference is only When you write your tests?

• Test-After is painful and boring.• Test-First makes unit testing easier. Unit Testing == Good.

Win win situation.

• Test-Driven-Design• Test-First drives the Design – Low Coupling.• Write only enough to make the test pass.• YAGNI

Automatic Test Generation?• Only possible after the code has been written.• You won’t get tests like…

• Test_that_user_registration_fails_on_invalid_ID()

• Doesn’t test Intent, can only test Methods.

Why testing efforts fail• When tests become frustrating

• Integration Tests != Unit Tests

• Slow• Brittle – break unnecessarily• Hard to Write due to highly coupled code.

Let’s test some code

What to test?• Single Responsibility Principle• Test the responsibility of the Controller Action.

• ApplicationSuccess view should be returned if application succeeds.

• ApplicationFailure view should be returned with a reason if application fails.

Our “Unit Test”

Database

Web Service

Session State

Step 1: Extract ClassSingle Responsibility Principle• Controller – Return correct view and viewModel• UserCreditService – Contains user credit checking functions

Step 2: Use fake Repository and fake UserCreditService

• Fake objects replace the functionality of the of the real object with an alternate implementaiton, ie returning a canned list of values instead of hitting a database

• Test Stub is an object that is used by a test to replace a real component to force the system down the path we want for the test. A stub may also record info about how it was called (ie. stub.wasMethodCalled())

• Mocks fake implementation by returning hard coded values or values preloaded - they can also verify that the correct calls were made in the right order

Injecting Fakes

ControllerTest

Controller

Fake DBRepo

Fake DBRepo

Creates…

Uses…

Tests…

Step 2: Fake object and Dependency Injection

Step 2: Fake object and dependency injection

Step 3: Abstract and Mock SessionA Mock Example…• Specify behaviours• Specify expectations• Works for Interfaces, Abstracts and Virtuals

Step 3: Abstract and Mock Session

Step 3: Abstract and Mock Session

TIPS

Tip: A handy private class

Tip• Fine grained is better

• 100 tests that test 100 things is better• … than 10 tests that test a 100 things.

• Execute the same action many times in different tests and verify different results in each call.

• Makes errors easier to isolate.

Tips• Break Dependencies – strive for low coupling

• Use Dependency Injection• Avoid public Statics• Avoid Singletons• Use Interfaces to abstract calls to other classes

• Use Mocks to mimic and test behaviour

• Single Responsibility Principle – break things into smaller classes and test independently.

</end>