Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Unit Testing


Published on

General information about Unit Testing practice

Published in: Technology, Business
  • Be the first to comment

Unit Testing

  1. 1. Unit Testing BasicsStanislav Tyurikov
  2. 2. Unit Test definitionUnit Test verifies the behavior of small elements in a softwaresystem, which are most often a single class or method. Every UTmust have several characteristics (F.I.R.S.T.):• Fasttakes a little time to execute (less than 0,01 sec).• Isolateddoes not interact with over parts of a system, failure reasons become obvious.• Repeatablerun repeatedly in any order, any time.• Self-Checkingno manual evaluation required.• Timelywritten before the code.
  3. 3. Types of testsUnit Test Component Test System Test Functional TestAlso known as Integration Test Acceptance TestDepends onExecution Time ms sec min hourDescriptionCheck class,methodTest componentintegrity, DBqueries.System API (WS,JNDI, etc), externalclient interactionCustomer oriented.Use UI controls,pages, links, etc.execution orderEach kind of test has its own area of responsibility, setup efforts, and accordingly,different execution time.
  4. 4. What Unit Test is not?Test is not a unit if:• Interacts with over parts of the system (DB, WS, FS, etc.).• Takes to much time to run (more than 0,01 sec).• Requires manual setup or verification.
  5. 5. Unit Test benefitsCorrectly organized and well designed unit tests givedevelopers several benefits:• Unit test as documentation.• Unit test as safety net.• Defect localization.• Needless of debugging.• Design improving.
  6. 6. Ineffective Unit TestWhen does test become a problem, not a solution?• Fragile Test – break too often.• Erratic Test – sometimes it pass and sometimes it fail.• Manual Intervention – a test requires a person to performsome manual action each time it is run.• Obscure Test – it is difficult to understand the test.• Slow Test – test takes too much time to run.
  7. 7. Principles of Test Automation• Write the Tests First• Design for Testability• Use the Front Door First• Don’t Modify the SUT• Keep Tests Independent• Isolate the SUT• Minimize Test Overlap• Minimize Untestable Code• Keep Test Logic Out of Production Code• Verify One Condition per Test• Ensure Commensurate Effort and Responsibility
  8. 8. How to start testing?For new code: Test Driven Development (aka Test First).If you have to add/modify feature on legacy code:• Identify change pointsFind places where you need to make your changes depend sensitively on yourarchitecture.• Find test pointsFind places where to write tests is easy.• Break dependencies.Make sure you can replace dependencies with stub/mock.• Write test.Implement test logic which reflects new requirements.• Refactor.Remove code duplication and smells.
  9. 9. Four-phase test executionsetupexecutionverificationteardownFixtureSUTUnit TestTerminology:• SUT – software under test.• Fixture – SUTs dependencies (environment).Phases:• Setup: create/find SUT or Fixture.• Execution: execute something on SUT.• Verification: Verify state or behavior of SUT/Fixture.• Teardown: clean up after test.
  10. 10. Simple Unit Test examplepublic class Statistics{public static double average(double[] data){if (isEmpty(data)) {throw newIllegalArgumentException("Data mustnt be empty.");}return calculateAverage(data);}private static double calculateAverage(double[] data){double sum = 0;for (int i = 0; i < data.length; i++) {sum += data[i];}return sum / data.length;}private static boolean isEmpty(double[] data){return data == null || data.length == 0;}}import org.testng.Assert;import org.testng.annotations.Test;public class StatisticsTest{@Testpublic void average(){final double[] data = {1, 2, 3, 4};final double expected = 2.5;final double result = Statistics.average(data);Assert.assertEquals(expected, result);}@Test(expectedExceptions = IllegalArgumentException.class)public void averageForNullData(){Statistics.average(null);}@Test(expectedExceptions = IllegalArgumentException.class)public void averageForEmptyData(){Statistics.average(new double[]{});}}Class to test: Test:
  11. 11. State verificationState verification almost used to:• Verify returned value.• Verify state of the SUT (Front Door).• Verify state of the Fixture (Back Door).
  12. 12. Behavior verification & Test DoublesBehavior verification used to check SUT correctly calls it’sfixture. General idea is replace fixture with test doubles (spiesor mock objects) and check them after test execution. Behaviorverification usually used when SUT is stateless.Test Spy – collects information about method calls. Forexample, count of specific method executions.Mock Object – record some scenario (order and count ofmethod calls), which must be reproduced on the executionphase. Checks itself on the verification phase.
  13. 13. EasyMock FrameworkEasyMock framework help us to create different kinds of test doubles. Wecan create double for an interface and class as well.Simple stubbing example:import org.easymock.EasyMock;import org.testng.Assert;import org.testng.annotations.Test;interface DataSource{String[] getData();}public class StubExample{@Testpublic void createStubByInterface(){final String[] dataToReturnByStub = {"value1", "value2"};final DataSource dataSource = EasyMock.createMock(DataSource.class);EasyMock.expect(dataSource.getData()).andStubReturn(dataToReturnByStub);EasyMock.replay(dataSource);Assert.assertEquals(dataSource.getData(), dataToReturnByStub);}}More information on
  14. 14. Behavior verification example with EasyMockpublic class Application{private IReportBuilder reportBuilder;private IEmployeeStatisticService statisticService;public Application(IReportBuilder reportBuilder, IEmployeeStatisticService statisticService){this.reportBuilder = reportBuilder;this.statisticService = statisticService;}/*** The execution flow of this operation is:* 1) Get statistics report data.* 2) Render report to a file specified.* @param fileName*/public void buildSalaryReport(Writer writer){final Map reportData = statisticService.createSalaryReportModel();reportBuilder.renderReport(reportData, writer);}}Class to test:
  15. 15. Behavior verification example with EasyMockimport org.easymock.EasyMock;public class ApplicationTest{private IReportBuilder createReportBuilderMock(Writer writerMock){final IReportBuilder reportBuilderMock = EasyMock.createMock(IReportBuilder.class);reportBuilderMock.renderReport(EasyMock.anyObject(Map.class), EasyMock.eq(writerMock));EasyMock.expectLastCall();return reportBuilderMock;}private IEmployeeStatisticService createEmployeeStatisticServiceMock(){final Map<String, Object> mockReturn = new HashMap<String, Object>();final IEmployeeStatisticService employeeStatisticServiceMock = EasyMock.createMock(IEmployeeStatisticService.class);EasyMock.expect(employeeStatisticServiceMock.createSalaryReportModel()).andStubReturn(mockReturn);return employeeStatisticServiceMock;}private Writer createWriterMock(){final Writer writerMock = EasyMock.createMock(Writer.class);return writerMock;}. . .}Mock setup methods:
  16. 16. Behavior verification example with EasyMockimport org.easymock.EasyMock;import org.testng.annotations.Test;public class ApplicationTest{. . .@Testpublic void applicationFlow(){// setup fixturefinal Writer writerMock = createWriterMock();final IEmployeeStatisticService employeeStatisticServiceMock = createEmployeeStatisticServiceMock();final IReportBuilder reportBuilderMock = createeReportBuilderMock(writerMock);EasyMock.replay(reportBuilderMock, employeeStatisticServiceMock, writerMock);// setup Application application =new Application(reportBuilderMock, employeeStatisticServiceMock);// execute test.application.buildSalaryReport(writerMock);// verify.EasyMock.verify(reportBuilderMock, employeeStatisticServiceMock, writerMock);}}Test method:
  17. 17. Basic Unit Test AntipatternsThe LiarExcessive SetupGiantThe MockeryThe InspectorGenerous LeftoversThe Local Hero (HiddenDependency)The NitpickerThe Secret CatcherThe DodgerThe LoudmouthThe Greedy CatcherThe SequencerThe EnumeratorThe StrangerThe Operating SystemEvangelistSuccess Against All OddsThe Free RideThe OneThe Peeping TomThe Slow Poke
  18. 18. Links and resources - Testing patterns. - TestNG framework home page. - EasyMock framework home page. - introduction to TDD methodology. - TDD anti-patterns.