Objectives
- Become familar the test framework and TDD in Smaltalk
Introduction
Test-Driven-Design is one of the more important tools for developing correct and reliable software to come along in years. Smalltalk is at the leading edge of this trend. Unit testing is a way to incrementally build an application without regressions on previously working parts. SUnit is the Smalltalk framework (and has been emulated in JUnit for Java, PyUnit or unittest for Python, NUnit for C#, ExUnit for Elixir, HUnit for Haskell, built into Rust, and many other frameworks for most common programming languages.
Problem Description
We're going to implement a simple stack in Smalltalk. It is going to have typical operations for stacks, as well as some special ones:
push: value
- pushes the value on top of the stackpop
- pops the top value of the stack and returns ittop
- returns the top value from the stack without any side-effect to the stackisEmpty
- returnstrue
if the stack is empty,false
otherwisedup
- push a copy of the top element onto the stackswap
- exchange the top two elements on the stackadd
- add the top two values on the stack, replacing them with the result; similarly formult
sub
- subtract the top value on the stack from the value below it, replacing them with the result; similarly fordiv
+ value
- add the immediate value to the top of the stack, leaving the result there; similarly for*
,-
, and/
where the immediate value is the right-hand argument~- value
- subtract the top of the stack from the immediate value, leaving the result there; similarly for~/
; these are like the previous ones, but the immediate value is the left-hand argument
Tests
- Create a package CPS506 if you haven't yet
- Create the class
Lab3Test
:TestCase subclass: #Lab3Test instanceVariableNames: '' classVariableNames: '' package: 'CPS506'
- Create the method
testBasic
in the class:testStack stack := Lab3Stack new. self assert: stack isEmpty. stack push: 42. self assert: stack top equals: 42. stack push: 17. self assert: stack top equals: 17. stack pop. self assert: stack top equals: 42. stack pop. self assert: stack isEmpty
- When you try to save it, you will see some error requiring you to define the
Lab3Stack
class (the default is fine), and where to put thestack
variable (may as well make it an instance variable). - When you have successfully saved it, you will see a little grey circle in front of the test name in the top-right panel (method list). You will see that there is another circle in front of the class name in the class list (top-2nd panel). Click that circle and it will run all the tests and give you a red pop-up notification (the notification fades in a few seconds if your mouse isn't over it).
- Click the circle in front of the test method name and it will run just that test, giving you a debug window if anything fails. From here you can create missing methods, single step code, inspect values of expressions (highlight them, then cmd-i or ctrl-i). Work through it until you get a green result. Clicking on the circle in front of the class will re-run all the tests, and should show green.
- Create a new method
testStack
to test the stack manipulation methods. Work through it, defining methods, until it's green too. Click on the circle in front of the class again to have it run all the tests, and verify you didn't break something else while fixing this one. - Create a new method
testArithmetic
to test the arithmetic operations, and work to get everything green.