assamtest

mocha-style tests for python
git clone https://git.ce9e.org/assamtest.git

commit
6c64c8167463a3bf4725b56c3c0096e408b8ffa1
parent
90a623c154abd783f7f5bd3ed7383d1f23d0b014
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2019-02-09 14:28
extend README

Diffstat

M README.md 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------

1 files changed, 70 insertions, 9 deletions


diff --git a/README.md b/README.md

@@ -1,4 +1,65 @@
    1    -1 ## `@test(name=None, args=[], decorators=[])`
   -1     1 assamtest is an experimental python test framework inspired by JavaScript
   -1     2 libraries such as [mocha](https://mochajs.org/) or
   -1     3 [jasmine](https://jasmine.github.io/).
   -1     4 
   -1     5 ```python
   -1     6 import assamtest
   -1     7 from assamtest import expect
   -1     8 
   -1     9 @assamtest.suite('A suite is just a function')
   -1    10 def my_suite():
   -1    11 	@assamtest.test('and so is a test')
   -1    12 	def my_test():
   -1    13 		a = True
   -1    14 		expect.true(a)
   -1    15 ```
   -1    16 
   -1    17 ```
   -1    18 $ pip install assamtest
   -1    19 $ assamtest
   -1    20 A suite is just a function
   -1    21   ✓ and so is a test
   -1    22 
   -1    23 ✓ 1 passed
   -1    24 ```
   -1    25 
   -1    26 ## Why another test framework?
   -1    27 
   -1    28 The idea for this library came out of my growing frustration with pytest,
   -1    29 especially its `parametrize` feature.
   -1    30 
   -1    31 In jasmine, parametrization is trivial:
   -1    32 
   -1    33 ```js
   -1    34 describe('#isNumber', function() {
   -1    35 	[1, 1000000, 0, -1].forEach(function(i) {
   -1    36 		it('recognizes ' + i, function() {
   -1    37 			expect(isNumber(i)).toBe(true);
   -1    38 		});
   -1    39 	});
   -1    40 });
   -1    41 ```
   -1    42 
   -1    43 This is because the tests are registered explicitly. The popular python test
   -1    44 frameworks (pytest, unittest) on the other hand use an implicit mechanism where
   -1    45 each function that starts with 'test\_' is registered. This makes
   -1    46 parametrization way harder than it needs to be.
   -1    47 
   -1    48 This library is an attempt to bring the explicit approach to python. However,
   -1    49 there are two important differences between the languages that make this
   -1    50 approach a bit less elegant in python:
   -1    51 
   -1    52 -	The test functions will never be called explicitly, so there is really no
   -1    53 	need for a name. But python does not have anonymous functions. Not a big
   -1    54 	deal, but still awkward, especially for things like `before_each` and
   -1    55 	`after_each`.
   -1    56 
   -1    57 -	In python, variables are local by default. If you want to write to variables
   -1    58 	from a descendant scope you have to use the `nonlocal` (or `global`) keyword.
   -1    59 
   -1    60 ## Reference
   -1    61 
   -1    62 ### `@test(name=None, args=[], decorators=[])`
    2    63 
    3    64 Register a function as a test:
    4    65 
@@ -16,7 +77,7 @@ def my_test(op, value):
   16    77 	assamtest.expect.equal(eval('2 %s 3' % op), value)
   17    78 ```
   18    79 
   19    -1 ## `@suite(name=None, args=[], decorators=[])`
   -1    80 ### `@suite(name=None, args=[], decorators=[])`
   20    81 
   21    82 Register a function as a suite:
   22    83 
@@ -37,19 +98,19 @@ def my_suite():
   37    98 
   38    99 The optional parameters are the same as for `test()`.
   39   100 
   40    -1 ## `@before()` / `@after()`
   -1   101 ### `@before()` / `@after()`
   41   102 
   42   103 Register a function to run before/after the whole suite.
   43   104 
   44   105 There can be only one `before`/`after` function per suite.
   45   106 
   46    -1 ## `@before_each()` / `@after_each()`
   -1   107 ### `@before_each()` / `@after_each()`
   47   108 
   48   109 Register a function to run before/after every test.
   49   110 
   50   111 There can be only one `before_each`/`after_each` function per suite.
   51   112 
   52    -1 ## `expect`
   -1   113 ### `expect`
   53   114 
   54   115 A wrapper around the asserts from `unittest.TestCase` using snake case:
   55   116 
@@ -65,7 +126,7 @@ with expect.raises(KeyError):
   65   126 
   66   127 See also the [full list of available assertions](https://docs.python.org/3/library/unittest.html?highlight=unittest%20testcase#assert-methods>).
   67   128 
   68    -1 ## `@decorators.skip`
   -1   129 ### `@decorators.skip`
   69   130 
   70   131 Do not execute the test at all::
   71   132 
@@ -79,7 +140,7 @@ def my_test():
   79   140 	expect.equal(2 + 2, 5)
   80   141 ```
   81   142 
   82    -1 ## `@decorators.fail`
   -1   143 ### `@decorators.fail`
   83   144 
   84   145 Invert the result of the test: If it would fail, pass instead. If it would
   85   146 pass, fail instead::
@@ -95,7 +156,7 @@ def my_test(value):
   95   156 	expect.equal(2 + 2, value)
   96   157 ```
   97   158 
   98    -1 ## `@decorator.synchronize`
   -1   159 ### `@decorator.synchronize`
   99   160 
  100   161 Start an asyncio event loop for the test and wait for it to complete::
  101   162 
@@ -113,7 +174,7 @@ async def my_test():
  113   174 	expect.equal(2 + 2, 4)
  114   175 ```
  115   176 
  116    -1 ## `Outcome(err, status, level)`
   -1   177 ### `Outcome(err, status, level)`
  117   178 
  118   179 Can be used to implement custom outcomes.
  119   180