Design, Development and Engineeringwebhost.bridgew.edu › jsantore › Spring2020 › GradSWEng ›...

Preview:

Citation preview

Design, Development and Engineering

Automated Testing, Test Driven Development

Soft Skills Podcast

● What did you think?– Except for the night class that just got assigned – we’ll

talk next week– How about the discussion on performance reviews?– On building network relationships?

Assignment

● Listen to

https://talkpython.fm/episodes/show/123/lessons-from-100-straight-dev-job-interviews

● Lessons from 100 straight job interviews.● For many of you some might be helpful.● This is a couple of years old now, and on the west coast, but I

think many of the lessons still carry over.

Version Control

● What do I mean by version control systems?

Version Control

● What do I mean by version control systems?– Software which will allow multiple team members to

work on code at the same time.– Competing revisions are merged more often than not.– Each time you update

● You are prompted to tell people what you changed

– Branches– Issues?

● (ask class)

Version Control?

● Widely used version control tools?– Old:

● ClearCase; Microsoft visual sourcesafe; cvs; svn

– It seems like open source solutions like git (especially online GitHub/GitLab) are becoming more and more common.

– Though Team Foundation Version Control (TFVC) From Microsoft and other proprietary solutions still exist too.

– What does github/gitlab buy you that other approaches don't?

Version Control?

● Two types of version control common today– Client server

● One canonical repository of code ● Each developer has a copy, uses client to get revisions to

local copy● Local copy needs to be synched

– Distributed● No canonical repository● All copies are working copies of software● No communication needed to update software in repository

– Only when communicating those to other peers

Version Control?● Version control jargon (should be review from ugrad

software eng):– Baseline

● A/the original version of file

– Check out● Get a local copy of the software (lock a file?)

– Commit● Write/merge changes back to repository

– Revision/version● A particular version of the file with all of the changes from

baseline to that point

– Diff● A particular set of changes

Version Control?

● Version control jargon (should be review from ugrad software eng):– Branch/fork

● A copy of the project which will be changed separate from the original main (trunk)

– Merge● Successfully adding your changes and other changes to the

same file● Or: successfully add changes to all files in trunk from a

branch

– Tag● A user friendly name to refer all of the files in a project as

they were at a specific time

Test Driven Development

● You have all heard of it– Because Software eng covers it– So what is it?– What does Test Driven Development (TDD) mean to

you?

Test Driven Development

● Tests come first before you write code– Purist version?

Test Driven Development

● Tests come first before you write code– Purist version?– Write test before you do anything.– Want to write a webapp?

● Before you do anything – including installing the web app libraries

– Write a test.– When it fails do something.

– So purist: write test, and only write real code when test fails.

Test Driven Development

● Purist approach.●

Automated Tests

● So I keep hearing about these tests– What kinds of tests do we care about?

Automated Tests

● So I keep hearing about these tests– What kinds of tests do we care about?

● Unit tests● Functional tests● Acceptance tests● What are each of these?

Automated Tests

● So I keep hearing about these tests– What kinds of tests do we care about?

● Unit tests– Item by item – function by function tests

● Functional tests– Does the app do what it is supposed to do?

● Acceptance tests– Does the app do what the client thinks it is supposed to do?

TDD

● So what are the tests supposed to do for us in Test Driven Development or other methods of using automated tests?– Why has Testing (TDD?) become so accepted in the

last 10-15 years?– Well actually some people still call it TDD but

‘automated tests’ might be a better term– What does Automated testing buy us?

TDD

● So what are the tests supposed to do for us in Test Driven Development?– Why has TDD become so accepted in the last 10-15

years?– Tests are run every time code is compiled/interpreted.– Tests become an extension of the compilers ability to

catch errors.– Always better to let the compiler catch the error.– Why?

– What does it buy us?

TDD for us

● I'm not a TDD purist– But the automated tests technique are still valuable– Automated tests of some sort are more or less

mandatory today.– Turn your specs into tests

● Unit tests● And functional tests● Write them,● Then write the code● Then run the tests● Every time you change anything and build

– Run all tests again

Assignment

● If you are not familiar with Test Driven Development– Read through chapter 2 of the test driven development

in python book linked from the resources page of the class website.

– If you have done Automated tests then lets move on.

Unit Tests

● Testing Smallest Testable part of application– Functions, methods, etc– Sometimes the entire public interface to a class– Extend compiler's error checking capability.

● Traditionally each unit test should be done in isolation– Even if your class relies on a database, mock database

and test class– Recently lots of conference talks pushing back against

mocks, tests on each unit will include its dependancies● We'll see if this takes

Unit/Automated Tests

● Available in nearly every important language– JUnit (grandaddy of all unit tests – written by Kent Beck

and Erich Gamma) – major updates with JUnit 5– Cheat for C– Googletest for c++– PyUnit for python(older library based on JUnit)– Pytest modern – can write tests without giant test

classes– Built-in for newer languages like golang and rust – etc

Automated Test Examples

● I’ll work through a testing example using pycharm and pytest

● If you are using java probably use junit● And intellij

● It should work very similarly.

New way: Pytest

● Pip install pytest.– I suggest through pycharm unless you have a linux distro

with a package manager.– Did it install correctly?– johns@Cicero:~$ pytest –version

This is pytest version 4.1.1, imported from /home/johns/.local/lib/python3.6/site-packages/pytest.py

Tell pycharm about pytest

● In pycharm choose settings● Then open the tools option and choose python

integrated tools.● In the default test runner option choose py.test

● Choose ok and close the dialog.

Best Practices

● For best practices,● Have a separate test directory● Create a new directory as a subdirectory in

your project● Lets call it tests.

What sorts of tests?

● What sorts of tests should we write?– Remember that many people suggest at least as much

test code as production code–

What sorts of tests?

● What sorts of tests should we write?– Remember that many people suggest at least as much

test code as production code– Want ‘happy path’ tests

● When all data is as expected

– Want bad data tests● When we enter junk● c.f little bobby tables

– Especially want to check unusual values● Like the (in)famous $0 billing statements

– Eventually want to try restricting resources● Simulate network outage for example.

First Automated Tests

● The first/easiest automated tests – Test a single function that computes a value– Usual starting demo online– Lets take a look at the work count project I did last year

on github– <right click on the test file> and ‘run pytest in <filename>’– Demo initial automated test and find ‘error’

Second test

● So the first happy path tries some easy wins– 3,4,5 triangle– Then we add in floating point answers– But floating point has precision and rounding issues for

repeating decimals and irrational decimals● you’ve heard this since CS1● Now we run into it with these tests

– For floating point numbers in pytest use ● Pytest.approx(<expected number>, <acceptable tolerance>)● Eg● assert pretendProductionCode.simple_distance(0, 0, 6, 5) ==

pytest.approx(7.81024967590, .000001)

JUnit Equivalent

● JUnit provides an equivalent – public static void assertEquals(double expected,– double actual,– double delta)– Version without delta is deprecated

● Example:– double myPi = 22.0d / 7.0d; //Don't use this in real life!– assertEquals(3.14159, myPi, 0.001);

● From:https://stackoverflow.com/questions/5939788/junit-assertequalsdouble-expected-double-actual-double-epsilon

Accepting Exceptions

● Sometimes you want your code to throw an exception– Want you automated tests to expect those– See code in class but– In test:

● with pytest.raises(TypeError): pretendProductionCode.add_interest("4", .05)

Accepting Exceptions

● Sometimes you want your code to throw an exception– Want you automated tests to expect those– See code in class but– In test:

● with pytest.raises(TypeError): pretendProductionCode.add_interest("4", .05)

– Want to have your production functions do proper error checking and sanity checking

● Want your tests to cover a full suite of possibilities

– Should add checks for 0 and 1 at least to the test suite.

Junit version

● In java/junit● Use ‘decorators’

– @Test(expected = IndexOutOfBoundsException.class) – public void empty() { – new ArrayList<Object>().get(0); – }

Unit testing and code design

● Variety of philosophies about production code and testing– Oldie and still used:

● Production code is what produces value for the company so it is the focus

– TDD/BDD influenced● Build production code to be easier to test

Example

● Build code to be tested– In production, this function prints to the command line– In python can monkey-patch, but not all languages let

you– So common solution: let the print location be a

parameter to the function (instance var)

Hard to test

● Some functions are hard to test:def show_output(): #this is hard to test initial_bal = 300 #we'll worry about this later balance = add_interest(1000, 0.025) print(f"Your new balance is ${balance}")

● How can we test print?–

Hard to test

● Some functions are hard to test:def show_output(initial_bal, rate): #this is hard to test balance = add_interest(initial_bal, rate) print(f"Your new balance is ${balance}")

● How can we test print?– We could do some crazy shell programming– Or Monkey-patch print and then put it back– Or we could write a testable function in the first place.– Suggestions?

Easier to test

● We can make the printing easier to test by taking another parameter.

def testable_show_output(initial_bal, rate, outfile): balance = add_interest(initial_bal, rate) if not outfile: outfile = sys.stdout print(f"Your new balance is ${balance}", file=outfile)

● So now when called from your production code, print prints to the screen as normal,– But we can write tests to have it print to a file

● With Java you can take a param of type PrintStream– Production code uses System.out

Lets try it

● I’ll use python and pytest, but you can use java/junit almost as easily, if you use gradle it is built in.– See

Assignment

● Start project 1 sprint 1

Recommended