Good Software Engineering

Build Status

Continuous Integration

The practice of integrating changes from different developers in the team...several times a day.

Is the code in a shared source control repository like git?

Is a central server (e.g. Travis CI) checking that it still builds?

Can failure be pointed back to a specific change?

Testing at every commit for quick feedback.

VSCodeTests

My CI + deployment pipeline for these slides!

Link to stackoverflow reference for below code

language: python # Set the build language to Python

python: 3.6 # Set the version of Python to use

branches:
  only:
  - gh-pages
  - /.*/ # Watch all branches pushed to github

# Install markdown checker
before_install:
  - sudo add-apt-repository -y ppa:mike42/mdcheckr
  - sudo apt-get update
  - sudo apt-get -y install mdcheckr

install:
    - pip install mkdocs # Install mkdocs
    - gem install mdl # Install markdown linter

script:
    - mdl docs/ ### Run markdown linter against docs/ folder
    - mdcheckr docs/*.md #### Check for broken images, link and code blocks

before_deploy:
    - mkdocs build --verbose --clean --strict ### Magic to create HTML from my markdown


deploy: # Push generated web files to GitHub
    provider: pages
    skip_cleanup: true
    github_token: $github_token
    local_dir: site
    on:
        branch: master # only publish slides from master

Automated Tests

Is the application covered by a comprehensive suite of tests that run automatically?

Testing Pyramid

Advantage of automated tests

Make code changes with confidence that tests will quickly spot if I break the existing behaviour.

I've been running unit tests locally and during a CI build for my Python.

VSCodeTests

(Not typical testing) I have a CI build at travis-ci.com for these very slides that:

alt text

Test Driven Development

Were tests written before any code?

Red ---> Green ---> Refactor

1. Failing test / red

A snapshot in time failing at test_no_name_given.

class TwoFerTest(unittest.TestCase):

    def test_a_name_given(self):
        self.assertEqual(two_fer("Alice"), "One for Alice, one for me.")

    def test_another_name_given(self):
        self.assertEqual(two_fer("Bob"), "One for Bob, one for me.")

    def test_no_name_given(self):
        self.assertEqual(two_fer(), 'One for you, one for me.')

2. Passing / green

Added an else condition to satisfy new test.

def two_fer(name=""):
    if name == "Alice":
        return ("One for Alice, one for me.")
    elif name == "Bob":
        return ("One for Bob, one for me.")
    else name == "":
        return('One for you, one for me.')

3. Refactored

Now that test passed (and the Rule of Three applied), I refactored.

def two_fer(name="you"):
    return (f"One for {name}, one for me.")

Advantages of TDD

Thank you

Things I didn't have time for