Multi-purpose tests (Cool tricks with JUnit) JavaZone 2012 Johannes Brodwall, Principal Architect Steria

Slides:



Advertisements
Similar presentations
Dependency injection when you only have one dependency JavaZone Johannes Brodwall, Recovering Spring User Steria Norway.
Advertisements

Ch. 2 Exploring core JUnit. This chapter covers ■ Using the core JUnit classes ■ Understanding JUnit mechanisms ■ Understanding the JUnit lifecycle.
Objectives: Test Options JUnit Testing Framework TestRunners Test Cases and Test Suites Test Fixtures JUnit.
API Design CPSC 315 – Programming Studio Fall 2008 Follows Kernighan and Pike, The Practice of Programming and Joshua Bloch’s Library-Centric Software.
CS 2110 Software Design Principles II Based on slides originally by Juan Altmayer Pizzorno port25.com.
JUnit. Why is testing good? Due to psychological factors, programmers are bad testers. A computer can test much faster than a human Philosophy: “If it.
Unit testing C# classes “If it isn’t tested it doesn’t work” Unit testing C# classes1.
14-Jul-15 JUnit 4. Comparing JUnit 3 to JUnit 4 All the old assertXXX methods are the same Most things are about equally easy JUnit 4 makes it easier.
Unit Testing Discussion C. Unit Test ● public Method is smallest unit of code ● Input/output transformation ● Test if the method does what it claims ●
Unit Testing Tips and Tricks: Database Interaction Louis Thomas.
Programmer Testing Testing all things Java using JUnit and extensions.
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
Test Driven Development TDD. Testing ”Testing can never demonstrate the absence of errors in software, only their presence” Edsger W. Dijkstra (but it.
Coding Dojo Agile Riga Day 2012 Johannes Brodwall, Principal Architect Steria
Extreme Startup Agile Riga Day 2012 Johannes Brodwall, Principal Architect Steria
Experience Agile Programming SDC 2012, Göteborg Johannes Brodwall Steria Featuring: Ole Chr Rynning.
The Use of Foreign Language Teaching Techniques in the Computer Science Laboratory to Support Oral Presentation and Group Work.
Unit Testing Bartosz Walter Software Engineering Lecture XXX.
Recap (önemli noktaları yinelemek) from last week Paradigm Kay’s Description Intro to Objects Messages / Interconnections Information Hiding Classes Inheritance.
Errors And How to Handle Them. GIGO There is a saying in computer science: “Garbage in, garbage out.” Is this true, or is it just an excuse for bad programming?
Test Driven Development Arrange, Act, Assert… Awesome Jason Offutt Software Engineer Central Christian Church
Using Aspects to Support the Software Process: XP over Eclipse Oren Mishali and Shmuel Katz Technion, Israel Institute of Technology.
Running Servlets JSDK2.1 default.cfg : Web Server configuration information batch files to start and stop server Servlet properties in /webpages/WEB-INF.
Junit At the forefront of Test Driven Development.
Testing in NetBeans. SWC Testing The ideal test: When the test is passed, the product is ready for delivery! Ideal – but (almost) impossible –Number of.
Threading Servlets Can handle multiple clients concurrently Shared resources must be synchronized or create a servlet that handles one request at a time.
1 CS122B: Projects in Databases and Web Applications Spring 2015 Notes 03: Web-App Architectures Professor Chen Li Department of Computer Science CS122B.
Refactoring & Testability. Testing in OOP programming No life in flexible methodologies and for refactoring- infected developers without SOME kind of.
Magnus
Chapter 8 Testing the Programs. Chapter 8 Learning Objectives Be able to …  Define different types of faults and how to classify them  Define the purpose.
Test-Driven Development Eduard Miric ă. The problem.
JUnit Don Braffitt Updated: 10-Jun-2011.
Scalatest. 2 Test-Driven Development (TDD) TDD is a technique in which you write the tests before you write the code you want to test This seems backward,
1 Introduction to Servlets. Topics Web Applications and the Java Server. HTTP protocol. Servlets 2.
Mark Dixon 1 11 – Java Servlets. Mark Dixon 2 Session Aims & Objectives Aims –To cover a range of web-application design techniques Objectives, by end.
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Testing Spring Applications Unit Testing.
Test it! Unit, mocking and in-container Meet Arquillian! Ivan St. Ivanov.
(1) Test Driven Development Philip Johnson Collaborative Software Development Laboratory Information and Computer Sciences University of Hawaii Honolulu.
Unit, Regression, and Behavioral Testing Based On: Unit Testing with JUnit and CUnit by Beth Kirby Dec 13, 2002 Jules.
Expect the Unexpected Kito D. Mann Principal Consultant.
Automated Testing in Sakai Testing applications and services in isolation and in context Josh Holtzman, UC Berkeley David Haines, University of Michigan.
Justin Bare and Deric Pang with material from Erin Peach, Nick Carney, Vinod Rathnam, Alex Mariakakis, Krysta Yousoufian, Mike Ernst, Kellen Donohue Section.
Experience Agile Programming Agile Meetup, Sri Lanka Johannes Brodwall Steria Featuring: Shihan Iqbal.
Coding Dojo Sofware People 2012 Johannes Brodwall, Principal Architect Steria
Introduction to Exceptions in Java CS201, SW Development Methods.
Enterprise Java v050228MVC1 Model, View, Controller Web Architecture.
1 © Agitar Software, 2007 Automated Unit Testing with AgitarOne Presented by Eamon McCormick Senior Solutions Consultant, Agitar Software Inc. Presented.
Software Testing Kobla Setriakor Nyomi Faculty Intern (Programming II)
SWE 434 SOFTWARE TESTING AND VALIDATION LAB2 – INTRODUCTION TO JUNIT 1 SWE 434 Lab.
CS122B: Projects in Databases and Web Applications Spring 2017
CS122B: Projects in Databases and Web Applications Winter 2017
Unit Testing.
Java Servlets By: Tejashri Udavant..
Unit Testing in a Team Sparkhound Presents by Steve Schaneville
Unit testing C# classes
In Class Assg 4 - Solution
In Class Assg 3 - Solution
History, Characteristics and Frameworks
null, true, and false are also reserved.
CS122B: Projects in Databases and Web Applications Winter 2018
In Class Assg 2 - solution
Test patterns.
CS122B: Projects in Databases and Web Applications Spring 2018
Automation of Testing in the Distributed Common Ground System (Army)
Automation of Testing in the Distributed Common Ground System (Army)
Automated test.
SOEN 343 Software Design Computer Science and Software Engineering Department Concordia University Fall 2004 Instructor: Patrice Chalin.
Designing For Testability
Joel Adams and Jeremy Frens Calvin College
CS122B: Projects in Databases and Web Applications Winter 2019
Presentation transcript:

Multi-purpose tests (Cool tricks with JUnit) JavaZone 2012 Johannes Brodwall, Principal Architect Steria

Part I

Properties of good test suites

Fast feedback Reasonable confidence in seconds

While you type! Holy crap! Get Infinitest!

Good coverage Never mind measured code coverage Do you catch many potential mistakes?

Robust Does refactoring break you tests? Do tests interfere with each other?

@Test public void should_filter_people() { Person person = Person.withName("Darth Vader"); Person nonMatching = Person.withName("Anakin Skywalker"); personRepository.savePerson(person); personRepository.savePerson(nonMatching); assertThat(personRepository.findPeople("vade")).contains(person).excludes(nonMatching); } While you type! Holy crap! Get Infinitest! “Act” and “assert” at same level of abstraction Allows for garbage in repository

Good test suites Fast feedback – ok confidence in seconds Coverage – breaks when they should Robust – don’t break when they shouldn’t

“Integration test” Sacrifice feedback for coverage

Part II

The configurable test

Starting point

public class PersonServletTest { private PersonServlet servlet = new PersonServlet(); private HttpServletRequest req = mock(HttpServletReq.class); private HttpServletResponse resp = mock(HttpServletResp.class); private PersonRepository personRepository = public void should_save_person() throws IOException { when(req.getParameter("full_name")).thenReturn("Darth Vader"); servlet.doPost(req, resp); verify(personRepository).savePerson(Person.withName("Darth Vader")); }

Fake instead of mock

public class PersonServletTest { private PersonServlet servlet = new PersonServlet(); private HttpServletRequest req = mock(HttpServletReq.class); private HttpServletResponse resp = mock(HttpServletResp.class); private PersonRepository personRepository = new public void should_save_person() throws IOException { when(req.getParameter("full_name")).thenReturn("Darth Vader"); servlet.doPost(req, resp); assertThat(personRepository.findAll()).contains(Person.withName("Darth Vader")); }

But we want also to use the real thing

public class PersonServlet WithRealRepo Test { private PersonServlet servlet = new PersonServlet(); private HttpServletRequest req = mock(HttpServletReq.class); private HttpServletResponse resp = mock(HttpServletResp.class); private PersonRepository personRepository = new public void should_save_person() throws IOException { when(req.getParameter("full_name")).thenReturn("Darth Vader"); servlet.doPost(req, resp); assertThat(personRepository.findAll()).contains(Person.withName("Darth Vader")); }

What if one test could do both?

@RunWith(RepositoryTestRunner.class) public class PersonServletTest { private PersonServlet servlet = new PersonServlet(); private HttpServletRequest req = mock(HttpServletReq.class); private HttpServletResponse resp = mock(HttpServletResp.class); private PersonRepository personRepository; public PersonServletTest(PersonRepository personRepo) { this.personRepository = personRepo; public void should_save_person() throws IOException { … }

I learned to write my own test runner by looking at org.junit.runner.Parameterized

The runner

public class RepositoryTestRunner extends Suite { private static JdbcConnectionPool dataSource = …; public RepositoryTestRunner(Class testClass) { super(testClass, createRunners(testClass)); } private static List createRunners(Class testClass) { List runners = new ArrayList<>(); runners.add(new RepoTestRunner(new FakePersonRepository(), testClass)); runners.add(new RepoTestRunner(new JdbcPersonRepository(dataSource), testClass)); return runners; } public static class RepoTestRunner extends BlockJUnit4ClassRunner {

public class RepositoryTestRunner extends Suite { public static class RepoTestRunner extends BlockJUnit4ClassRunner { private PersonRepository personRepo; RepoTestRunner(PersonRepository personRepo, Class testClass) { super(testClass); this.personRepo = personRepo; } protected Object createTest() throws Exception { return getTestClass().getOnlyConstructor().newInstance(personRepo) ; } protected void validateConstructor(List errors) { validateOnlyOneConstructor(errors); }

The result

Keeping it honest

@RunWith(RepositoryTestRunner.class) public class PersonRepositoryTest { private PersonRepository personRepository; public PersonRepositoryTest(PersonRepository personRepository) { this.personRepository = personRepository; public void should_filter_people() { Person person = Person.withName("Darth Vader"); Person nonMatching = Person.withName("Anakin Skywalker"); personRepository.savePerson(person); personRepository.savePerson(nonMatching); assertThat(personRepository.findPeople("vade")).contains(person).excludes(nonMatching); }

Part III

The big picture

Worth it?

Thought experiment: What if you could test your whole application without connecting to anything?

Maintain fakes or Speed up realz?

Maintain fakes or Speed up realz?

Other uses

public class XmlSerializationTest { private final File xmlFile; public XmlSerializationTest(File xmlFile) { this.xmlFile = xmlFile; public void serializedShouldMatch() { assertThat(normalize(Xml.read(xmlFile).toXML())).isEqualTo(normalize(slurp(xmlFile))); }

Conclusions

There’s more to tests than “integration test” or “unit test”

Get fast feedback Detect mistakes Only fail when you should

Thank you

“Integration tests or unit tests”

Integration tests or unit test?

public class JdbcPersonRepositoryTest { private static DataSource public static void createDataSource() { dataSource = JdbcConnectionPool.create(…); JdbcPersonRepository.createDatabaseSchema(dataSource); } PersonRepository personRepo = new public void should_save_people() { Person person = Person.withName("Johannes Brodwall"); personRepo.savePerson(person); assertThat(personRepo.findPeople(null)).contains(person); }

“Integration tests” Connects to services, database, files? Or just integrates whole system? Or integrates system with all services?

“Integration tests” are Slow Dependent on external systems Realistic?

Integration tests or unit test?

public class PersonTest public void equality() { assertThat(Person.withName("Darth Vader")).isEqualTo(Person.withName("Darth Vader")).isNotEqualTo(Person.withName("Anakin Skywalker")).isNotEqualTo(new Object()).isNotEqualTo(null); } Since you’re asking: FEST-assert

“Unit tests” No resources outside JVM? Only one class? Only one method?

“Unit tests” are Very fast Coupled to implementation?

Integration tests or unit test?

Why does it matter?

Who is this talk for? You have written more than a few tests in JUnit You want to find out when you write unit test and when to write integration tests and how to use mocks well You will be able to write your own test-runner for fun and profit

What will I cover Testing considerations Unit test or integration test What are good tests Mocks versus fakes Creating your own test runner The mocked test The faked test The multi purpose test What’s next? Eventually abandoned But still in many cases – eg. Files