Unit Testing in Ruby SWEN-250 Personal Software Engineering - - PowerPoint PPT Presentation
Unit Testing in Ruby SWEN-250 Personal Software Engineering - - PowerPoint PPT Presentation
Unit Testing in Ruby SWEN-250 Personal Software Engineering Testing, 1 2 3 4, Testing What Does a Unit Test Test? The term unit predates the O -O era. Unit natural abstraction unit of an O -O system: class
Testing, 1 – 2 – 3 – 4, Testing…
What Does a Unit Test Test?
- The term “unit” predates the O-O era.
- Unit – “natural” abstraction unit of an O-O
system: class or its instantiated form, object.
- Unit Tests – verify a small chunk of code,
typically a path through a method or function.
- Not application level functionality.
Unit Testing Review
- Test a cohesive functional entity:
– Class – Stand alone function or functions
- Verification testing – does the entity do what
it's supposed to do.
- Greatly facilitated by unit test frameworks.
– JUnit for Java – NUnit for .NET – MiniTest::Test for Ruby
How Do We Unit Test?
- Print Statements (diffs against benchmarks)
- Debuggers – examine variables, observe
execution paths.
- Typically done by unit developer.
- Best benefit if running of tests is automated.
- Tests best run in isolation from one another.
- Tests built incrementally as product code is
developed.
The Typical Test Cycle
- Develop a suite of test cases
- Create some test fixtures to support the
running of each test case.
- Run the test – capture test results.
- Clean-up fixtures, if necessary.
- Report and analyze the test results.
Why is Unit Testing Good?
- Identifies defects early in the development
cycle.
- Many small bugs ultimately leads to chaotic
system behavior
- Testing affects the design of your code.
- Successful tests breed confidence.
- Testing forces us to read our own code –
spend more time reading than writing
- Automated tests support maintainability and
extendibility.
Why Don’t We Unit Test?
- “Coding unit tests takes too much time”
- “I’m to busy fixing bugs to write tests”
- “Testing is boring – it stifles my creativity”
- “My code is virtually flawless…”
- “Testing is better done by the testing
department”
- “We’ll go back and write unit tests after we
get the code working”
Basic xUnit Components
- Create a test class that extends class Test
- Create a testxxx() method for each individual
test to be run.
- Create a test fixture – resources needed to
support the running of the test.
- Write the test, collect interesting test behavior
- Tear down the fixture (if needed)
- Run the tests.
Key xUnit Concepts
- assert -
– assertEquals( expected, actual ) – also NotEquals – assertNull( actual result ) – also NotNull – assertTrue( actual result) - also False
- failures –
– Exceptions raised by asserts (expected)
- errors –
– Ruby runtime exceptions (not expected)
Unit Testing in Ruby
- MiniTest::Test
– All unit test classes inherit from this class – Example: class MyClass < MiniTest::Test – setup / teardown – test* methods run in random order
- Assertions (change assert to refute for negative)
– assert(boolean, [message]) – assert_equal(exp, act, [message]) – assert_raises(Exception) block – assert_nil(obj, [message]) – Full list in
http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest/Assertions.html
Queue: (queue.rb)
cl class ass Q Queu ueue # # Ex Excep epti tion
- n cl
clas ass f for
- r t
taki king ng va valu lues es fr from
- m an
an e emp mpty y qu queue ue. cla class ss Em Empty pty < < Sta Standa ndardE rdError ror def def ini initia tializ lize supe uper(" r("Empt mpty y que queue" ue") end end end end # I # Ini nitia tializ lizatio tion def def init nitial ialize ze @co @conte ntents nts = = Arr Array. ay.new new sel self end end # Q # Que ueue ue is is empt mpty y if if its its siz size e is is zer zero def def empt mpty? y? siz size = e == 0 = 0 end end # Q # Que ueue ue siz size - nu numbe mber o r of el elem ement ents def def size ize @co conte ntents nts.siz size end end
Queue: (queue.rb)
# A # Add dd a a val value t e to
- the
the ta tail o l of f the the qu queue ue def def t tail ail= v = value lue @co @conte ntents nts[@co @cont ntent ents.s s.size] ze] = = v valu alue val value ue end end # R # Ret eturn urn th the fi firs rst e t elem lement nt in in th the q e queue eue w with ithout
- ut rem
remov
- ving
ing it it def def p peek eek rai raise se Emp Empty i y if f emp empty? ty? @c @cont nten ents ts[0] 0] end end # R # Ret eturn urn an and re remo move ve the the fir first st qu queue eue ele eleme ment nt def def h head ead val value ue = p = peek ek @co @conte ntents nts.del delet ete_a e_at(0 t(0) val value ue end end en end
TestQueue: (test_queue.rb)
require ‘minitest/autorun' require_relative ‘queue' cl class ass T Test estQue Queue < e < M Mini iniTes Test::T ::Tes est def def s setu etup @tq @tq = = Que Queue.n e.new ew end end # C # Che heck ck pro proper er em empty pty qu queue ue be behav havior ior def def t test est_ne _new_qu _queu eue ass assert ert( @ ( @tq.s q.siz ize = e == 0 = 0, "N "New ew qu queue eue siz size e not not ze zero"
- " )
ass assert ert( @ ( @tq.e q.emp mpty? ty?, " , "New ew qu queue eue no not em empt pty" y" ) as asser ert_ t_ra raise ses( s(Que ueue ue:: ::Emp mpty ty) { { @ @tq tq.pe peek ek } ass assert ert_ra _raises ses(Q (Queu ueue:: e::Empt mpty) y) { { @tq @tq.hea head d } end end
TestQueue: (test_queue.rb)
# C # Che heck ck pro proper er FI FIFO FO beh behavio vior.
- r. Mu
Must st end nd wi with th an an empt mpty y que queue. ue. def def test est_fi _fifo_c
- _che
heck ck tes test_v t_valu alues = % = %w{ w{ A B A B C } C } # # init init an a n arr rray ay of
- f thre
hree e val values ues tes test_v t_valu alues.e s.eac ach { | { |v| v| @ @tq. tq.tai tail = = v } v } # # ad add t d to th the e que queue ue siz size = e = @ @tq tq.si .size ze # e # expe xpect ct 3 3 for for th the qu queu eue s e size ize tvl tvlen en = = te test_ st_va value lues.l s.lengt ngth ass assert ert( s ( size ze == == tvlen tvlen, "# "#{tvl tvlen} e } elem lement ent q queu ueue g e gives ves s size ize of
- f #{s
#{siz ize}" e}" ) ) ref refute ute( @ ( @tq.e q.emp mpty ty?, ?, "N "Non
- n-em
empty pty qu queue ue re repor ports ts empt mpty" y" ) ) #It #Itera erate te thro hroug ugh t h the he arra rray y and and re remove
- ve e
each ach on
- ne en
entr try tes test_v t_valu alues.e s.eac ach do do |v |v| qv = v = ni nil #d #dec eclar lare v e varia riabl ble t e to p
- pass
ss be betwe tween en asse ssert rtion ions qv = v = @ @tq tq.pe .peek ek # n # no e
- exce
xcept ption ion if if cod code e is is cor correct ect ass sser ert_ t_equ qual al(v, v, q qv, v, '@ '@tq tq.pe peek ek:') :') qv qv = @ @tq tq.he .head ad asse ssert_ rt_equa qual(v, v, qv, qv, '@ '@tq. tq.hea head:') :') end end ass assert ert_ra _raises ses(Q (Queu ueue:: e::Empt mpty) y) { { @tq. tq.pee peek } # } #emp empty n y now
- w
as asser ert_ t_ra raise ses(Q (Que ueue ue:: ::Emp mpty ty) { { @ @tq tq.he head ad } end end en end