COMP2013Lecture4
>
>
Lecture 04
Super Awesome Useful Coding Tools
(including testing principles)
Dr. Julie Greensmith
>
>
Today’s learning objectives
• To be able to write self documenting code using Javadoc
• To appreciate how to write very useful code comments
• To understand build files
• To lean how build files help to produce automation in testing
• Software testing:
– Unit tests
– Regression tests
– Property testing e.g. QuickCheck for Haskell
• Why you should use Debugging tools but probably don’t
• Check your work from last week’s lab session
COMP/2013 2
>
>
Self Documenting Code
Tips and tricks for using JavaDoc
COMP2013-Autumn 2018 3
>
COMP2013-Autumn 2018 4
*Completely not true brah*Listen to Darth Vader yo
>
Eclipse is a really helpful IDE
(even if it is a bit clicky clicky pointy)
• Many of todays tools are built into Eclipse
• It is useful beyond providing us with a nice interface, project viewer and telling us
of precompile errors, missing libraries and spelling mistakes
• It is great for helping us create maintainable code including in-built testing help
• Autogeneration of self documenting code with the help of a tool called Javadoc
• This comes with the JDK and requires you to tag your code with special
comments
• Has special syntax to differentiate it from regular comments
• /** …….*/ as opposed to /* … */
COMP2013-Autumn 2018 5
>
Useful Javadoc Tags
• Syntax: @
• Really useful for generating comments which are quite tedious to write in full the
whole time and then to have to ‘grep’ or ‘sed’ using regexs
• It generates a really easy to use HTML based output as a living document
• Updated each time you compile if Javadoc is on the compilation path
• Some famous tags:
– @param: to explain a parameter
– @return: to annotate a return value
– @throws/@exception: for your error handling
– @deprecated: bits of the code you no longer use
– {@code}: puts syntax in your documentation
COMP2013-Autumn 2018 6
>
Javadoc.
Its awesome, lets do some!
COMP2013-Autumn 2018 2
>
Build Files
Makefiles, not war.
COMP2013-Autumn 2018 8
>
COMP2013-Autumn 2018 9
>
Makefiles are magic
• Old people like me who grew up on C and C++, it was all about the makefiles
• A way of automating the compilation process in a world before eclipse did everything for
you
• Used to develop in environments like Gvim, Emacs and Vi
– Visual basic was for L05erZ
• When you had lots of classes and libraries they were really useful
• Also used for installing new packages
COMP2013-Autumn 2018 10
$ make clean all install
hellomake: hellomake.c hellofunc.c gcc -o
hellomake hellomake.c hellofunc.c -I.
gcc -o hellomake hellomake.c hellofunc.c -I.
>
Build files: Beyond the Scope of a basic package
• Both ECLIPSE AND INTELLIJ can cope with us both writing loads of classes and our
own packages
• So far in our examples we have not used many external resources
• Build files are like a super amazing versions of makefiles which are used by old
people who work with things like C and C++
• They are massively useful when you have lots of extra things like:
– Games engines
– Package dependencies
– Test harnesses including Junit
• As soon as you use code from other developers, you need a Build File
COMP2013-Autumn 2018 11
>
Build Files are really helpful for maintenance
• It can be really helpful in ensuring code portability
– It means that your friend doesn’t need to have exactly the same coding environment as you
– Eliminates class path problems if the build file is constructed
• They can get really complicated: teams often have a member who works only on
a build file
• They ensure consistent compilation and eliminates “Classpath” problems
• It allows you to integrate:
– Testing frameworks
– Automated quality metrics
– Deployment in unknown environments
COMP2013-Autumn 2018 12
>
Common frameworks for Build Files
• There are three main ones used by developers:
– 1. Ant: https://ant.apache.org
– 2. Maven: https://maven.apache.org
– 3. Gradle :
• Lets have a look in detail at Ant (one of the oldest and widely used)
• Compare and contrast these tools
• Note: although there is inbuilt support in IDEs like eclipse for these tools, many
developers prefer to run them through the command line
– For both brevity and simplicity
COMP2013-Autumn 2018 13
>
Apache Ant
• ‘Ant’ is a standard tool for Build Files for
Java: “Another Neat Tool”
• It is very similar to the principles of ‘make’
only it is optimized and constructed with
java and not C in mind
• Make is not quite as good with Java due to
things like the JVM
• Ant is now about 20 years old
• XML based in the build file with special tags
COMP2013-Autumn 2018 3
>
Anatomy of an Ant Build File
• Contains: Project and Target
• Constructed: quite strict xml
• Example, like ‘make clean’:
COMP2013-Autumn 2018 15
< delete dir = “$(build)” >
>
Other interesting Ant facts
• It is the most complete tool for Java builds, but this can get tedious
• Its great at automating repetitive tasks
– Can be used to write a custom framework for testing
• It has a massive list of pre-defined tasks, yet provides the facility to create your
own custom tasks
• Can be run using command line but is also integrated into many IDEs
– Eclipse can generate these for you, we will do this in the lab
• However: It is a bit deprecated these days: most prefer Maven, as in Ant you
need to specify everything explicitly
COMP2013-Autumn 2018 16
>
COMP2013-Autumn 2018 17
>
It generates a build.xml file which you can then edit
COMP2013-Autumn 2018 18
You get two views for the price of one.
You can look at the XML file directly in
the IDE file window or you can use the
Ant viewer itself
>
COMP2013-Autumn 2018 19
>
Maven*: Less tedious than Ant
• Its more of a pro-choice issue like Eclipse vs
IntelliJ or Emacs vs Vim or Diet Coke vs Pepsi
Max
• Maven’s strength is that it manages for you the
use of dependencies
– With Ant you have to do this manually, but
Ant remains more flexible
• “Convention over Configuration”
– Maven relies on conventions and provides
predefined commands as goals
*not installed by default on Flexible desktop
COMP2013-Autumn 2018 3
>
Gradle: A Contemporary
Approach
• Released 2012 (so most modern of the three).
• Tried to take best parts of Ant and Maven
• Dispenses with XML in favour of a domain
specific language
• Declarative: plug-ins add functionality
• More cleanly accomplishes required tasks of a
typical development project, from compilation
through testing and deployment.
• It’s the official build system for Android
COMP2013-Autumn 2018 2
>
Reading homework comparing Build File Tools
• Interesting blog articles for you to read
comparing the two:
– http://www.adam-
bien.com/roller/abien/entry/maven_vs_ant
– https://www.baeldung.com/ant-maven-
gradle
COMP2013-Autumn 2018 7
http://www.adam-bien.com/roller/abien/entry/maven_vs_ant
https://www.baeldung.com/ant-maven-gradle
>
Testing
One of the Cornerstones of Maintainable Software and Software Maintenance
COMP2013-Autumn 2018 23
>
COMP2013-Autumn 2018 24
>
Testing your code is the most important process
• Software testing is the foundation on which software development is based
• Little to no point in writing code if you are not going to test it
• Many different aspects of testing exist:
– Developing a testing strategy
– Unit testing
– Test Driven Development with Junit
– Property based testing
• Testing and debugging are often used synonymously
COMP2013-Autumn 2018 25
>
Famous Quotes On Testing
2
• “Debugging is what you do when you know your program
is broken. Testing is a determined, systematic attempt to
break a program that you think is working.”
– Brian Kernighan and Rob Pike, The Practice of
Programming
• “Testing can demonstrate the presence of bugs but not
their absence”
– Edsgar Dijkstra
>
Get Rid Of The Arrogance!
• We all like to think that the code we write is perfect in construction and so that
we have no need for systematic and extensive coverage
• This assumption of belief can lead to catastrophic consequences
– Buffer overflow exploits and many other security flaws
– Challenger disaster
– Radiation poisoning due to decimal point error
• Testing can start as small as checking a value has been copied correctly or as large
as using a completely automated continuous integration server
• In essence, test, test you tests, and test your test testing.
COMP2013-Autumn 2018 27
>
Coding best practice to minimize errors
• The more automation you use in your development process, the fewer errors you
are likely to introduce
• If your code writing feels mechanical, then it should be mechanized
– Autogeneration from frameworks like visual paradigm or auto class method stub generation
in Eclipse
– Using regular expressions to specify patterns of text and variable sets
– Using autocomplete tools where available to avoid simple typing errors and mistakes
• In general, if a generator is correct, specification is covered, the
interpreter/compiler is correct, so too will be the resulting program
– Sometimes though we really cannot make these assumptions without testing
COMP2013-Autumn 2018 28
>
Test Your Code As You Write
• The biggest difference between a person who has learnt to code versus a
seasoned developer is in the mindset regarding testing
• The earlier a problem is found, the easier it is to fix
– Repeatable errors and bugs are usually ok to track down
– Use assistance from a debugger, putting breakpoints and watches on variables
• Transient or intermittent faults are an absolute nightmare
– Ensuring effective testing coverage minimizes the chance of this scenario
• Professional developers write code with testing at the forefront of their minds
COMP2013-Autumn 2018 29
>
”But I’m confident in my code that its correct!”
• Even the most simple of operations should be tested as they are written
• As a result more complex bugs do not get the chance to occur
• It is a grave mistake to make that just because something compiles or Eclipse says
its ok, it does not mean that it does not need to be tested
• We will initially look at Boundary Testing
COMP2013-Autumn 2018 30
>
Test Code At Its Boundaries
• Boundary condition testing is the absolute minimum amount of testing that you
should perform
• It involves probing the natural boundaries within a small unit of your code
• Based n the assumption that most errors will occur at the boundaries
• Examples:
– Non existent or empty input
– Single item input
– Completely full array
– While loop conditions and sentinels
– Logical statements
COMP2013-Autumn 2018 31
>
What can go wrong with this simple example function?
double avg(double gradesArray[], int n){
int i;
double sum;
sum = 0.0;
for (i = 0; i < n; i++){
sum += gradesArray[i];
}
return sum/n;
}
COMP2013-Autumn 2018 32
>
Things that will go wrong
• So n can represent the full set of integers: it’s a good idea to test the boundary of
the smallest value which is zero, 0.
• An array with no elements is meaningful to the function but a value of n=0 to
calculate an average is not
• Question: what should this function do?
– Continue with division by zero and return not a number (nan)?
– Abort the program?
– Complain to the programmer?
– Return an erroneous random value?
– Simply return the integer zero?
• return n <= 0 ?0.0: sum/n; ?? COMP2013-Autumn 2018 33 >
The answer is NEVER….
• TO DO NOTHING!!!!
• In the olden days we would print stuff to standard error stream and save this to a
log file so we could read our failure conditions
• There are more modern, less archaic strategies.
COMP2013-Autumn 2018 34
>
Assert( ) Using Assertions in pre/post condition testing
• Java, C, C++, python etc. have an assertion testing facility to add pre and post
conditions to ensure that these assertions are validated
• Assertions are used to abort the program when a condition fails
• Example: we could have added assert(n>0) to our previous function to avoid the
division by zero
• Rarely see this style of coding in student coursework!
– Have you been taught this? If so, why are you not using it?
– If not, learn how to use it!
COMP2013-Autumn 2018 35
>
Program Defensively: “It’ll Never Happen”
• We didn’t think that Trump would be president of the USA or that Brexit would
be happening either, just makes you think eh.
• No matter how you think through how a program will be used you need to
account for unlikely or rare situations
– This is another fault I see frequently in labs and in student coursework
• Example:
– “A user would never enter a negative value for their age”
– “This file will always be created by the other class that I have written”
• Also as software is maintained or changed it can cause changes to values, files,
data, class structure, available methods, that you cant always predict
• The process of performing these simple tests on small units of code is called….
COMP2013-Autumn 2018 36
>
…Unit Testing
• This can be WHITE BOX or BLACK BOX testing
• Question: If you know how to do this, why have so many of you forgotten to do
this while developing the zoo app in our labs?
– The answer to this needs to be anything but laziness!
• When writing code and managing your build you should always know what the
expected output is of every method, the size of every buffer and the type of
every variable
– Its not tedium, its precision!
• Testing can ensure you have coded what you intended to code if you write the
tests first, even if you do this on paper.
COMP2013-Autumn 2018 37
>
COMP2013-Autumn 2018 38
>
Regression Testing
• This is a major concept in Software Maintenance
• When you make changes to a codebase you test the new code added AND the
whole rest of all the code in the application
• Your modification may have broken the existing code
– Never just test that the fix you have implemented works
• This requires extensive, systematic and automated methods for testing programs
• Otherwise the complexity of the testing becomes far too big to manage
COMP2013-Autumn 2018 39
>
Regression Testing with Test Scaffolds
• You can do a DIY small scale approach
• A test scaffold to interface and run hundreds, thousands, millions of tests EVERY
TIME THE CODE COMPILES
• NB: We couldn’t do this without build files which help to construct scaffolds
– Many JUnit tutorials require you to understand how to use Maven
• Tools and frameworks exist to aid this automation
• Big projects with many people use continuous integration servers (next week)
• Test suits or scaffolds rely on the same principle as writing with minimum errors:
“if it can be mechanized then it should”
COMP2013-Autumn 2018 40
>
DIY Approaches With UNIX Tools
• Much of the code you develop for your coursework or projects is not large
enough in scope to warrant a large test scaffold
• There are some simple techniques you can use to help you do this effectively and
quickly
• Classic UNIX tools can help: wc cmp diff grep freq
• Create yourself a log file where the results of your tests are stored
• Use UNIX tools to compare the test logs before and after you’ve made changes to
the code
COMP2013-Autumn 2018 41
>
COMP2013-Autumn 2018 42
for i in Ka_data.* //loop through test logs
do
old_ka $i >out1 //run old version
new_ka $i >out2 //run new version
if !cmp -s out1 out2 //compare logs
then
echo $1: Is_bad //outputs that there’s a problem
diff out1 out2
wc out1 out2
fi
done
This script only produces any output if there is a problem, it
runs silently
>
>
BREAK TIME
YOU HAVE 7 MINUTES
COMP2013-Autumn 2018 43
>
Unit Testing With Help From JUnit
• When code gets very complex you will need to employ some help from a library
that allows us to build a test harness/scaffold
• Today we will look at Junit as it works nicely with the Java based principles we are
teaching in this course
• In real life, the business analyst or product owner will provide some sample input
and output to an application
• Junit is not part of the standard JDK, but provides an interface or API to a testing
library
• It allows for extensive test coverage
• NB it does not do integration tests!!
COMP2013-Autumn 2018 44
>
Adding Junit to your project
• You can simply add junit.jar to your Classpath or add it to you xml in your Ant or
Maven Build File
– Junit is already supported in Eclipse and NetBeans
• Can use a test driven development approach of writing your tests in Junit BEFORE
you write your code
– Tests all fail at fist as there isn’t any code
– Once you have added all of your code and it passes all the tests, you are done
• You can achieve exceptional coverage of your code using this method
• Remember, you have to run all the tests every time you compile, so it is put in a
separate testing folder
COMP2013-Autumn 2018 45
>
The Best Way To Understand
Junit, is to use Junit.
COMP2013-Autumn 2018 11
>
COMP2013-Autumn 2018 47
>
Property Based Testing : A New Hope
• A long time ago in A Haskell Galaxy, far, far away
• Wanted to prove properties of basic functional operation
• Extension exercise for your PGP coursework
• Ensures that a program satisfied specified properties across a huge variety of
input
• Sometimes we cant think of every permutation of an input for unit testing
• In TDD it is possible to gain maximum coverage over all statements but not over
all conditions and inputs
COMP2013-Autumn 2018 48
>
PBT Process:
• Example: Heart rate monitor software which checks the range of Heart Rate and
sounds an alarm if the values are out of range
– With unit testing it would be extremely difficult to check every single value in the range for
this type of input
– Yet, this is a Safety Critical System and so this should be done
• Property based testing specifies the outputs and the range of inputs:
1. Define the behaviors you want to test
2. Define the range of data to check against each outcome
3. Generate test datasets which can be totally random to completely specified
4. Write and run the tests
• The tool QuickCheck is used to assist developers in this task
– And its related tool smallCheck
COMP2013-Autumn 2018 49
>
QuickCheck for Property Based Testing
• Property based testing is almost synonymous with QuickCheck which is an
extremely popular tool
• It started out life just for functional languages like Haskell and Erlang
– Has been commercially extended for use in other languages, also gaining popularity
• Provides an elegant framework for supporting up to brute force style stress
testing of program properties
– E.g. has a list which has been inverted and reinverted returned the original list?
– Do recursive functions return the correct output
• Learning to use QuickCheck in our labs is unfortunately out of scope, but we
would like you to be aware of its power and existence
• https://www.youtube.com/watch?v=AfaNEebCDos
COMP2013-Autumn 2018 50
>
Testing Summary
• Testing is a crucial part of both creating maintainable software and software
maintenance
• Testing must be an ongoing and integral part of software development, no matter
what the scale of the development
• Very basic techniques can be very effective
• Unit testing can be scaffolded using JUnit for Java (other similar fwks exist)
• Test Driven Development is where JUnit tests are written before code
functionality
• QuickCheck and Property Based Testing can be used to verify properties and test
unthinkable amounts of scenarios
COMP2013-Autumn 2018 51
>
Put it all together now
• All of the tools today have not been grouped together by accident
• While you are writing your unit tests, write your Javadoc comments
• Put both JUnit and your files on the Classpath and automate the process using a
build file
• It becomes trivial to run your entire suite of tools each time you compile and you
can ensure that in regression testing that your new fix does not break existing
code
• The combination of these tools is what you need to work at any kind of
reasonable scale
• Next time: How this works with repository software to manage change and code
integration techniques
COMP2013-Autumn 2018 52