Unit Testing in Ruby 22-Feb-19.

Slides:



Advertisements
Similar presentations
Test-First Programming. The tests should drive you to write the code, the reason you write code is to get a test to succeed, and you should only write.
Advertisements

Annoucements  Next labs 9 and 10 are paired for everyone. So don’t miss the lab.  There is a review session for the quiz on Monday, November 4, at 8:00.
CIT 590 Unit testing.
1-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
JUnit. What is unit testing? A unit is the smallest testable part of an application. A unit test automatically verifies the correctness of the unit. There.
1 Software Testing and Quality Assurance Lecture 23 – JUnit Tutorial.
JUnit, Revisited 17-Apr-17.
21-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
22-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
23-Jun-15 Unit Testing in Ruby. Programming methodologies The grim facts: The majority of large programming projects fail Projects that succeed are usually.
24-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
24-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
Computer Science 1620 Programming & Problem Solving.
26-Jun-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests.
15-Jul-15 JUnit. 2 Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (testing whatever occurs.
Test Driven Development Derived from Dr. Fawcett’s notes Phil Pratt-Szeliga Fall 2009.
CIT 590 Unit testing. Agenda Debugging attempt 2 (because I am stubborn) What is unit testing Why? Unit testing framework in Python.
By for Test Driven Development: Industry practice and teaching tool Robert Vanderwall, Ph.D. 1 WISTPC-15.
TDD,BDD and Unit Testing in Ruby
Test Driven Development TDD. Testing ”Testing can never demonstrate the absence of errors in software, only their presence” Edsger W. Dijkstra (but it.
Test Driven Development An approach to writing better code Jimmy Zimmerman Intel Corporation.
© Dr. A. Williams, Fall Present Software Quality Assurance – JUnit Lab 1 JUnit A unit test framework for Java –Authors: Erich Gamma, Kent Beck Objective:
Testing in Extreme Programming
ICAPRG301A Week 4Buggy Programming ICAPRG301A Apply introductory programming techniques Program Bugs US Navy Admiral Grace Hopper is often credited with.
Test automation / JUnit Building automatically repeatable test suites.
Dr. Tom WayCSC Testing and Test-Driven Development CSC 4700 Software Engineering Based on Sommerville slides.
(1) Unit Testing and Test Planning CS2110: SW Development Methods These slides design for use in lab. They supplement more complete slides used in lecture.
Introduction to JUnit 3.8 SEG 3203 Winter ‘07 Prepared By Samia Niamatullah.
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
A tool for test-driven development
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,
Copyright 2007 SpringSource. Copying, publishing or distributing without express written permission is prohibited. Testing Spring Applications Unit Testing.
CPSC 217 T03 Week VI Part #1: A2 Post-Mortem and Functions Hubert (Sathaporn) Hu.
Agenda: Overview of Agile testing Difference between Agile and traditional Methodology Agile Development Methodologies Extreme Programming Test Driven.
Unit Testing with FlexUnit
25-Feb-16 Extreme Programming. 2 Software engineering methodologies A methodology is a formalized process or set of practices for creating software An.
PHPUnit Julia Bondar IAPM23. Agenda What is PHPUnit How to write an automated test Writing and running tests with PHPUnit Advantages and disadvantages.
Today protected access modifier Using the debugger in Eclipse JUnit testing TDD Winter 2016CMPE212 - Prof. McLeod1.
Test automation / JUnit Building automatically repeatable test suites.
Automated Testing with PHPUnit. How do you know your code works?
SWE 434 SOFTWARE TESTING AND VALIDATION LAB2 – INTRODUCTION TO JUNIT 1 SWE 434 Lab.
Software Development - Methodologies
Software Development.
Debugging Intermittent Issues
Introduction to JUnit CS 4501 / 6501 Software Testing
C++ coding standard suggestion… Separate reasoning from action, in every block. Hi, this talk is to suggest a rule (or guideline) to simplify C++ code.
More JUnit CS 4501 / 6501 Software Testing
Test Driven Development 1 November Agenda  What is TDD ?  Steps to start  Refactoring  TDD terminology  Benefits  JUnit  Mocktio  Continuous.
Chapter 8 – Software Testing
Debugging Intermittent Issues
Computer Science 209 Testing With JUnit.
Software Engineering 1, CS 355 Unit Testing with JUnit
Information Hiding Example
History, Characteristics and Frameworks
JUnit 28-Nov-18.
JUnit 28-Nov-18.
Test-driven development (TDD)
Testing and Test-Driven Development CSC 4700 Software Engineering
Introduction to JUnit CS 4501 / 6501 Software Testing
JUnit 7-Dec-18.
JUnit 11-Jan-19.
More JUnit CS 4501 / 6501 Software Testing
Information Hiding Example
JUnit 18-Apr-19.
Extreme Programming.
JUnit Reading: various web pages
JUnit 31-May-19.
Test-Driven Development
Unit Testing.
Presentation transcript:

Unit Testing in Ruby 22-Feb-19

Programming methodologies The grim facts: The majority of large programming projects fail Projects that succeed are usually full of bugs Modifying and debugging programs usually introduces yet more bugs Hence, it is hazardous to modify a “working” program The time spent maintaining a program far exceeds (10x?) the amount of time it took to write the program Programming methodologies are attempts to solve these problems by properly organizing programs and/or programmers The current (and best) methodologies are the “agile” methodologies “Agile” means writing software that is easily changed XP (Exteme Programming) is the best known agile methodology XP tends to work best for small groups of programmers

Some ideas from agile programming There is no “silver bullet,” but agile methodologies are the best we have at present Most large programming projects fail, so... “Write the simplest thing that can possibly work.” Always have a working version, no matter how little it does Never add a feature until all known bugs have been fixed Any code that hasn’t been tested is assumed to be wrong Have tests for all code, and keep it up to date Run tests frequently—very frequently Tests must be trivially easy to run, or you won’t bother running them

Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (running whatever tests occur to you at the moment), or You can build a test suite (a thorough set of tests that can be run at any time) Disadvantages of a test suite It’s a lot of extra programming This is true, but use of a good test framework can help quite a bit You don’t have time to do all that extra work False—Experiments repeatedly show that test suites reduce debugging time more than the amount spent building the test suite Advantages of a test suite Reduces total number of bugs in delivered code Makes code much more maintainable and refactorable This is a huge win for programs that get actual use!

XP approach to testing In the Extreme Programming approach, Tests are written before the code itself If code has no automated test case, it is assumed not to work A test framework is used so that automated testing can be done after every small change to the code This may be as often as every 5 or 10 minutes If a bug is found after development, a test is created to keep the bug from coming back Consequences Fewer bugs More maintainable code Continuous integration—During development, the program always works—it may not do everything required, but what it does, it does right

Terminology A test fixture sets up the data (both objects and primitives) that are needed to run tests Example: If you are testing code that updates an employee record, you need an employee record to test it on A unit test is a test of a single class A test case tests the response of a single method to a particular set of inputs A test suite is a collection of test cases A test runner is software that runs tests and reports results An integration test is a test of how well classes work together JUnit provides some limited support for integration tests

Once more, in pictures test runner test fixture test suite test runner another unit test test case (for one method) another test case A unit test tests the methods in a single class A test case tests (insofar as possible) a single method You can have multiple test cases for a single method A test suite combines unit tests The test fixture provides software support for all this The test runner runs unit tests or an entire test suite Integration testing (testing that it all works together) is not well supported by JUnit another unit test another test case unit test (for one class) test case (for one method) another test case test fixture

The test runner The test runner runs all your tests If they all succeed, you get a green bar If any fail, you get a red bar and links to the tests that failed

How not to write a unit test Unit tests must be fast and easy to run—or you won’t run them The only output you should need to look at, in order to see that all tests passed, at is the green bar Of course, if you get a red bar, you need to explore further Don’t do any output from your unit tests! Ideally, the methods you are testing should not do any output In most well-written programs, there is a separation of concerns—methods either compute or do output, but not both It is possible to write unit tests for methods that do output, but that is a slightly advanced topic I won’t cover here

How to write a unit test class A unit test class is a class you write that extends Test::Unit::TestCase You will need the line require 'test/unit' Your test class will inherit the following methods: def setup This a method that will be called before each of your test methods Typically, you will override this method and use it to assign values to some instance variables you need in testing def teardown() This a method that will be called after each of your test methods Typically you will just ignore this method, unless you need to close files You will also write any number of test methods, all of which have the form def test_Something Something is usually, but not necessarily, the name of the method you want to test Inside each test method, you will do some computations and call one or more assert methods to test the results

Available assertion methods assert boolean assert_equal expected, actual Uses == assert_same expected, actual Uses equal? assert_not_equal expected, actual assert_not_same expected, actual assert nil object assert not_nil object assert_block block All these methods can take an additional message argument This is not a complete listing of the assert methods The first two methods are by far the most commonly used

Structure of a unit test require "test/unit" require "file_to_be_tested" class CountTest < Test::Unit::TestCase def setup # Perform initializations here end def test_some_method # Tests go here end def teardown # Release any resources (usually not needed) end end

Testing for exceptions Methods should throw exceptions if they are called incorrectly You can test whether a method throws an exception when it ought to def test_exceptions begin # Call the method that should throw an exception rescue Exception # or you can test for specific exceptions return # The exception happened, so the test passes end flunk end Ruby also has assert_raise and assert_throws methods, but I haven’t been able to make them work

A complete example class Counter attr_reader :value def initialize @value = 0 end def increment *n if n == [ ] @value += 1 else @value += n[0] end end def reset @value = 0 end end

The test class, part 1 require "test/unit" require "counter" class CountTest < Test::Unit::TestCase def setup @c = Counter.new end def test_increment_with_no_args assert_equal 0, @c.value @c.increment assert_equal 1, @c.value @c.increment assert_equal 2, @c.value end def test_increment_with_arg assert_equal 0, @c.value @c.increment 3 assert_equal 3, @c.value @c.increment 5 assert_equal 8, @c.value end def test_reset @c.increment @c.increment 10 assert @c.value > 0 @c.reset assert @c.value.zero? end

The test class, part 2 def test_exceptions begin @c.increment 'four' return rescue Exception end flunk end end # of the test class

Test suites A test suite is a collection of unit tests In Ruby, all you have to do is require each test file Example suite (containing just the one unit test: require 'ruby_tests‘ Note: In RadRails, running a test suite produces only text output

Test-Driven Development (TDD) It is difficult to add unit tests to an existing program The program probably wasn’t written with testing in mind It’s actually better to write the tests before writing the code you want to test This seems backward, but it really does work better: When tests are written first, you have a clearer idea what to do when you write the methods Because the tests are written first, the methods are necessarily written to be testable Writing tests first encourages you to write simpler, single-purpose methods Because the methods will be called from more than one environment (the “real” one, plus your test class), they tend to be more independent of the environment

Recommended approach Write a test for some method you intend to write If the method is fairly complex, test only the simplest case Write a stub for the method Run the test and make sure it fails Replace the stub with code Write just enough code to pass the tests Run the test If it fails, debug the method (or maybe debug the test); repeat until the test passes If the method needs to do more, or handle more complex situations, add the tests for these first, and go back to step 3

The End If you don't unit test then you aren't a software engineer, you are a typist who understands a programming language. --Moses Jones 1. Never underestimate the power of one little test. 2. There is no such thing as a dumb test. 3. Your tests can often find problems where you're not expecting them. 4. Test that everything you say happens actually does happen. 5. If it's worth documenting, it's worth testing. --Andy Lester