Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible improvment to chapter 3 example 3 #89

Closed
enkidulan opened this issue Aug 19, 2019 · 2 comments
Closed

Possible improvment to chapter 3 example 3 #89

enkidulan opened this issue Aug 19, 2019 · 2 comments

Comments

@enkidulan
Copy link

enkidulan commented Aug 19, 2019

The following construction from Chapter 03 Example 3:

    try:
        source = tempfile.mkdtemp()
        dest = tempfile.mkdtemp()
       ...
    finally:
        shutil.rmtree(source)
        shutil.rmtree(dest)

is a use-case for TemporaryDirectory context manager:

def test_when_a_file_exists_in_the_source_but_not_the_destination():
    with tempfile.TemporaryDirectory() as source,\
           tempfile.TemporaryDirectory() as dest:

        content = "I am a very useful file"
        (Path(source) / 'my-file').write_text(content)

        sync(source, dest)

        expected_path = Path(dest) /  'my-file'
        assert expected_path.exists()
        assert expected_path.read_text() == content

Another option is to use pytest's tmpdir fixture. That would reduce number of lines even more:

def test_when_a_file_exists_in_the_source_but_not_the_destination(tmpdir):
    source = tmpdir.mkdir("source")
    dest = tmpdir.mkdir("dest")
    source.join("my-file").write("I am a very useful file")
    sync(source, dest)
    dest.join("my-file").read() == "I am a very useful file"

And there is one more thing. I understand that these end-to-end test-cases are only for demonstration of the disadvantages of tightly coupled architecture, but they do not seem very realistic to me. I would use stubs for the end-to-end testing and I would have only one test-case for that, which would rather look like this:

def test_sync_end_to_end(tmpdir):
    source = tmpdir.mkdir("source")
    dest = tmpdir.mkdir("dest")
    shutil.copytree(stub_source, source)
    shutil.copytree(stab_dest, dest)
    sync(source, dest)
    assert not filecmp.dircmp(dest, stub_source).diff_files

this test still has the same problems and disadvantages of the original test-cases, like high cost of testing all business rules and inability to test them separately and in isolation. Which actually is not the use-case for end-to-end testing. I've just understood the source of my confusion. Chapter 3 started with creating "bad" end-to-end tests and replaced them with "good" unit and edge-to-edge tests at the end of the chapter by improving the architecture of sync function. So I was under impression that the message is that it is wrong to write end-to-end tests (well, maybe I'm just a bad reader). But the point, probably, is that with the initial architecture of sync it's impossible to write unit tests, and using end-to-end testing in unit-test maner is a bad idea.

@hjwp
Copy link
Contributor

hjwp commented Aug 28, 2019

  1. I did not know about tempfile.TemporaryDirectory, thanks very much for that! maybe we'll leave the listing deliberately ugly for now tho

  2. yes you're right, the point is not "e2e tests are bad" but "using e2e tests to cover business logic / edge cases is bad (or at least annoying)" .

we try and say that a bit more in the service layer chapter section called 'what kinds of tests should I write'. we should say it more explicityly here too...

@enkidulan
Copy link
Author

Thank you! :)

@hjwp hjwp closed this as completed in e44404e Nov 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants