forked from coala/cEPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cEP-0027.md: Add
Improve Lint Bear Quality
cEP
This proposes the prototype of the feature of BaseTestHelper class and GlobalBearTestHelper class. BaseTestHelper class will be a normal base class, and it will grow from there later. GlobalBearTestHelper in coala testing API will add supports to the GlobalBear. Ref coala/coala#3676 Ref coala/coala#4884
- Loading branch information
1 parent
1ec5b92
commit 1d1a8a9
Showing
1 changed file
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
# coala Bears Testing API | ||
|
||
| Metadata | | | ||
| -------- | ----------------------------------------- | | ||
| cEP | 27 | | ||
| Version | 0.1 | | ||
| Title | coala Bears Testing API | | ||
| Authors | Sangam Kumar <mailto:[email protected]> | | ||
| Status | Proposed | | ||
| Type | Feature | | ||
|
||
## Abstract | ||
|
||
This cEP describes the process of adding `BaseTestHelper` class and | ||
`GlobalBearTestHelper` class to improve the testing API of coala bears, as a | ||
part of the [GSoC 2018 project](https://summerofcode.withgoogle.com/projects/#6625036551585792). | ||
|
||
## Introduction | ||
|
||
[coala](https://coala.io) has its own testing API which includes | ||
`LocalBearTestHelper`, a helper class for testing of local bears. It does not | ||
provide support for `GlobalBear`. Writing tests for a `GlobalBear` is slightly | ||
lengthy for a developer. Example: | ||
[GitCommitBearTest](https://github.com/coala/coala-bears/blob/master/tests/vcs/git/GitCommitBearTest.py), | ||
[VultureBearTest](https://github.com/coala/coala-bears/blob/master/tests/python/VultureBearTest.py), | ||
etc. `GlobalBearTestHelper` is going to be a helper class for simplification of | ||
testing of `GlobalBear`. | ||
|
||
Also, the testing API should have a base test helper class which should be | ||
inherited in all tests' helper (LocalBearTestHelper, GlobalBearTestHelper). | ||
This project introduces `BaseTestHelper` class, base class for all bear tests. | ||
|
||
## Proposed Approach | ||
|
||
### 1. Implementation of the `BaseTestHelper` class | ||
|
||
Issue: [coala/coala#3676](https://github.com/coala/coala/issues/3676) | ||
|
||
As mentioned in [introduction](#Introduction), `BaseTestHelper` class is the | ||
base class for all bear tests. | ||
|
||
```py | ||
class BaseTestHelper(object): | ||
pass | ||
``` | ||
|
||
Now, inherit the base test class in `LocalBearTestHelper` and | ||
`GlobalBearTestBear`. E.g., | ||
|
||
```py | ||
class LocalBearTestHelper(BaseTestHelper): | ||
pass | ||
|
||
class GlobalBearTestHelper(BaseTestHelper): | ||
pass | ||
``` | ||
|
||
After implementation of `BaseTestHelper` class, it should be ensured that all | ||
bear tests inherit from `BaseTestHelper` class using [pytest-restrict](https://pypi.org/project/pytest-restrict). | ||
For example, in [`LocalBearTestHelperTest`](https://github.com/coala/coala/blob/master/tests/testing/LocalBearTestHelperTest.py), | ||
|
||
```py | ||
out = self.runpytest('--restrict-types', | ||
'BaseTestHelper', | ||
'LocalBearTestHelper') | ||
out.assert_outcomes(passed=2, failed=0) | ||
``` | ||
|
||
### 2. Implementation of `GlobalBearTestHelper` class | ||
|
||
Issue: [coala/coala#4884](https://github.com/coala/coala/issues/4884) | ||
|
||
Currently, many methods are redundant in the tests of `GlobalBear`. For | ||
example, all GlobalBears' tests have one method to collect absolute path of | ||
test files and then those files are checked using the bear. | ||
|
||
```py | ||
def get_absolute_test_path(file): | ||
return "path/of/test_file/file" | ||
|
||
def get_results(self, files_to_check): | ||
self.file_dict = [get_absolute_test_path(files_to_check)] | ||
self.uut = AnyGlobalBear(self.file_dict, self.section, self.queue) | ||
return list(self.uut.run()) | ||
|
||
def test_results(self): | ||
results = self.get_results([self.test_files1, self.test_files2]) | ||
messages = [result.message for result in results] | ||
assert messages == ["This is message 1.", | ||
"This is message 2."] | ||
``` | ||
|
||
Instead of writing these methods each time during tests of `GlobalBear`, it | ||
should be written once in `GlobalBearTestHelper` class with less flaws and | ||
better design which will be easy to reuse and less effort will be required to | ||
maintain. | ||
|
||
Here is the prototype implementation of these repeating methods into | ||
`GlobalBearTestHelper` using [pytest](https://pytest.org/), and | ||
[GlobalBear](http://api.coala.io/en/latest/coalib.bears.html#module-coalib.bears.GlobalBear): | ||
|
||
```py | ||
def get_test_path(test_dir, file): | ||
return os.path.join(os.path.dirname(__file__), test_dir, file) | ||
|
||
def get_results(global_bear, test_dir, file_dict, settings={}): | ||
for file in file_dict: | ||
with get_test_path(test_dir, file) as fname, | ||
execute_bear(global_bear, fname, **settings) as bear_output: | ||
return bear_output | ||
|
||
@contextmanager | ||
def execute_bear(bear, *args, **kwargs): | ||
try: | ||
bear_output_generator = bear.execute(*args, **kwargs) | ||
assert bear_output_generator is not None, \ | ||
'Bear returned None on execution\n' | ||
yield bear_output_generator | ||
except Exception as err: | ||
msg = [] | ||
while not bear.message_queue.empty(): | ||
msg.append(bear.message_queue.get().message) | ||
raise AssertionError(str(err) + ' \n' + '\n'.join(msg)) | ||
return list(bear_output_generator) | ||
|
||
|
||
class GlobalBearTestHelper(BaseTestHelper): | ||
def check_results(self, global_bear, test_dir, file_dict, results, settings={}): | ||
if results in [[], ()]: | ||
msg = ("The global bear '{}' yields a result although " | ||
"it shouldn't.".format(global_bear.__class__.__name__)) | ||
|
||
else: | ||
msg = ("The global bear '{}' doesn't yield the right " | ||
"results.".format(global_bear.__class__.__name__)) | ||
|
||
bear_output = get_results(global_bear, | ||
test_dir=test_dir, | ||
file_dict=file_dict, | ||
settings=settings) | ||
|
||
assert bear_output == results, msg=msg | ||
return bear_output | ||
``` |