This repository was archived by the owner on Sep 21, 2019. It is now read-only.
Add unit testing framework, pytest #327
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I've been doing a bit of work on a project to extract a core ENSIME client for Python that could potentially be shared with ensime-sublime or others (more of a rewrite of the core than extraction, but I'll save this whole discussion until it's really ready to talk about).
I set up unit test infrastructure for that project from the start and thought about whether to add it to ensime-vim too, but wasn't sure if there was a need yet. Now that I've started some work on #321, it's finally there—we're finally getting to the point where some substantial logic will be decoupled enough from complex dependencies to feasibly be unit tested. I've mentioned before how I think Lettuce is ideal for integration/acceptance/end-to-end tests but unit tests are a better fit for other cases.
An example is the config file parsing, which we had Lettuce tests for but they feel heavy because there's no need for integration there, it's extra work to write steps in code plus a prose feature for something so low-level. So I used that as a small contained example case for the initial unit test framework setup, converting those to unit tests and taking the opportunity to abstract it in a cute little mapping class that I've used in my spinoff project.
Briefly, a rundown of popular unit testing choices in the Python ecosystem—there are three main contenders:
unittest
module.unittest
has the advantage of being built-in, but it's very much jUnit-inspired and ceremonious: everything is a class, and the worst to me is that you need to learn a bunch of differentassert*
methods.Nose and pytest by contrast share a lot in common, they both aim to be lightweight frameworks that are highly-plugin driven and let you just write simple functions, scaling up to using more complicated structures if you feel the need to. I chose Pytest for a few reasons:
unittest
for assertions with nose acting as a test runner, or use the built-inassert
statement with not-very-good failure output, kind of like with Lettuce where there is more burden on you to write string explanations for assertions. pytest has badass output with simple standard assert statements.A couple of things that might be negatives for pytest: it is somewhat "magical": its fantastic output for standard
assert
is achieved through bytecode manipulation. That said, it's been around for many years and is regarded as solid. Also, it has a novel approach to setup/teardown or test fixtures that is like dependency injection—it's actually quite nice and scales up and down very flexibly, but it takes a bit of getting used to since it is unusual. As the doc mentions, there is still support for classical setup/teardown functions at different scopes, though.Let me know what you think. I'd ideally like to base my work for #321 atop this test setup as well as the logging in #323.