Test Driven Development Flow

So lastly I've introduced to myself a Test Driven Development, but unfortunatelly I didn't examine the flow and approach as much as I should.

Thanks to Uncle Bob I've realized what exactly TDD flow looks like.

1. Make a test that (should) fail.

The idea is not to make any type of source code before test-code, but instead, create a test that probably will fail if you haven't got any source-code.

2. Pass your failing test

Make your initial test not failing by creating just enought source-code for this particular test.

3. Refactor your source code.

Then finally refactor your code to look better.

4. Repeat steps 1-3 untill your source-code does what you expect it from.

Check this awesome image that will help me with TDD approach in this initial days of working in this system:

TDD Global Lifecycle by Wikipedia

What I did wrong this time ? :)

Well... this time I've figure out that I'll make a bunch of tests for all bunch of functions that will help me focus on small elements in a short period of time (pomodoro technique-remember?)

Then I ofcourse would normally start working on this tests to make a TDD approach.

But let's follow TDD in a different way.

Let's use this information I've gathered as more "documentation" of what should be done, then how this code should look like.

Initial test.

Lets first create a test for our plugin:

def test_plugin_registers():
    """
    Check if plugin registers to article_generator_finalized
    """
    register()
    assert_receiver_registered(fancybox_plugin)

And then make source-code that will pass test (that's a refactored code):

def register():
    "Registers plugin"
    signals.article_generator_finalized.connect(fancybox_plugin)

def assert_receiver_registered(receiver_name):
    'Checks if receiver is registered to signals generator'
    assert signals.article_generator_finalized.has_receivers_for(receiver_name)

def test_plugin_registers():
    """
    Check if plugin registers to article_generator_finalized
    """
    register()
    assert_receiver_registered(fancybox_plugin)

Final result

I've made thus far 3 tests that checks few simple but needed things.

For now final result looks like this:

"""
FancyBox unittests
"""
from pelican import signals

class Article(object):
    "A simple Article class"
    content = ""

def article_generator():
    "Article generator"
    yield Article()

def fancybox_plugin():
    "Fanxybox plugin - temporary code placement"
    pass

def register():
    "Registers plugin"
    signals.article_generator_finalized.connect(fancybox_plugin)

def assert_receiver_registered(receiver_name):
    'Checks if receiver is registered to signals generator'
    assert signals.article_generator_finalized.has_receivers_for(receiver_name)

def test_plugin_registers():
    """
    Check if plugin registers to article_generator_finalized
    """
    register()
    assert_receiver_registered(fancybox_plugin)

def test_article_generator_return_article():
    """
    Checks if generator return article
    """
    assert isinstance(article_generator().next(), Article)

def test_given_article_generator_check_article_content_exists():
    "Checks if article content field exists in article"
    for article in article_generator():
        assert hasattr(article, 'content')

Code commits done for this post:

Tools and applications used:

  • vi/vim
  • pytest
  • docker
  • tmux

Accomplished:

1. Make tests for fancybox plugin

What's next

1. Make more tests and source-code of fancybox plugin

2. Start working on plugin for asciinema player.

3. See ISSUES task-list for this 'mini' growing project :)



Comments

comments powered by Disqus