Skip to content

Commit

Permalink
cEP-0027.md: Add Improve Lint Bear Quality cEP
Browse files Browse the repository at this point in the history
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
sangamcse authored and gitmate-bot committed May 29, 2018
1 parent 1ec5b92 commit 1d1a8a9
Showing 1 changed file with 144 additions and 0 deletions.
144 changes: 144 additions & 0 deletions cEP-0027.md
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
```

0 comments on commit 1d1a8a9

Please sign in to comment.