Add unittest patch (#77)
This commit is contained in:
parent
4dab3e218a
commit
7b41752775
22
README.md
22
README.md
@ -45,6 +45,26 @@ better_exceptions.MAX_LENGTH = None
|
||||
|
||||
While using `better_exceptions` in production, do not forget to unset the `BETTER_EXCEPTIONS` variable to avoid leaking sensitive data in your logs.
|
||||
|
||||
### Use with unittest
|
||||
|
||||
If you want to use `better_exceptions` to format `unittest`'s exception output, you can use the monkey patch below:
|
||||
|
||||
```python
|
||||
import sys
|
||||
import unittest
|
||||
import better_exceptions
|
||||
|
||||
def patch(self, err, test):
|
||||
lines = better_exceptions.format_exception(*err)
|
||||
if sys.version_info[0] == 2:
|
||||
return u"".join(lines).encode("utf-8")
|
||||
return "".join(lines)
|
||||
|
||||
unittest.result.TestResult._exc_info_to_string = patch
|
||||
```
|
||||
|
||||
Note that this uses an undocumented method override, so it is **not** guaranteed to work on all platforms or versions of Python.
|
||||
|
||||
### Django Usage
|
||||
|
||||
_Tested with Django 1.11_
|
||||
@ -81,8 +101,6 @@ example output:
|
||||
|
||||
![image](https://user-images.githubusercontent.com/157132/56871937-5a07b480-69f1-11e9-9fd5-fac12382ebb7.png)
|
||||
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you do not see beautiful exceptions, first make sure that the environment variable does exist. You can try `echo $BETTER_EXCEPTIONS` (Linux / OSX) or `echo %BETTER_EXCEPTIONS%` (Windows). On Linux and OSX, the `export` command does not add the variable permanently, you will probably need to edit the `~/.profile` file to make it persistent. On Windows, you need to open a new terminal after the `setx` command.
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -219,3 +219,20 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python2 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m│ └ <function add at 0xDEADBEEF>[m
|
||||
[36m└ <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m │ └ '2'[m
|
||||
[36m └ 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
└ <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
│ └ <function add at 0xDEADBEEF>
|
||||
└ <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
│ └ '2'
|
||||
└ 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
[36m-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>[m
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add([31m1[m, [31m'2'[m), [31m3[m)
|
||||
[36m| -> <function add at 0xDEADBEEF>[m
|
||||
[36m-> <__main__.MyTestCase testMethod=test_add>[m
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
[33;1mreturn[m a + b
|
||||
[36m | -> '2'[m
|
||||
[36m -> 1[m
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
@ -209,6 +209,25 @@ SyntaxError: invalid syntax
|
||||
|
||||
|
||||
|
||||
python3 test/test_unittest_patch.py
|
||||
|
||||
|
||||
return a + b
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
testMethod()
|
||||
-> <bound method MyTestCase.test_add of <__main__.MyTestCase testMethod=test_add>>
|
||||
File "test/test_unittest_patch.py", line 15, in test_add
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
| -> <function add at 0xDEADBEEF>
|
||||
-> <__main__.MyTestCase testMethod=test_add>
|
||||
File "test/test_unittest_patch.py", line 10, in add
|
||||
return a + b
|
||||
| -> '2'
|
||||
-> 1
|
||||
TypeError: unsupported operand type(s) for +: 'int' and 'str'
|
||||
|
||||
|
||||
|
||||
python3 test/test_chaining.py
|
||||
|
||||
|
||||
|
56
test/test_unittest_patch.py
Normal file
56
test/test_unittest_patch.py
Normal file
@ -0,0 +1,56 @@
|
||||
import io
|
||||
import sys
|
||||
import unittest
|
||||
import better_exceptions
|
||||
|
||||
STREAM = io.BytesIO() if sys.version_info[0] == 2 else io.StringIO()
|
||||
|
||||
|
||||
def add(a, b):
|
||||
return a + b
|
||||
|
||||
|
||||
class MyTestCase(unittest.TestCase):
|
||||
def test_add(self):
|
||||
self.assertEqual(add(1, "2"), 3)
|
||||
|
||||
|
||||
class SilentTestRunner(unittest.TextTestRunner):
|
||||
"""
|
||||
The default TextTestRunner will print something like 'Ran 1 test in 0.017s'
|
||||
into stderr, and values are different from different tests. To ensure that
|
||||
CI script can compare between the outputs, those information must be muted.
|
||||
"""
|
||||
|
||||
def __init__(self, stream=STREAM, *args, **kwargs):
|
||||
super(SilentTestRunner, self).__init__(STREAM, *args, **kwargs)
|
||||
|
||||
|
||||
def print_test_error():
|
||||
test = unittest.main(exit=False, testRunner=SilentTestRunner)
|
||||
error = test.result.errors[0][1]
|
||||
# unittest.TestResult.errors is "A list containing 2-tuples of TestCase
|
||||
# instances and strings holding formatted tracebacks. Each tuple represents
|
||||
# a test which raised an unexpected exception."
|
||||
assert isinstance(error, str)
|
||||
lines = error.splitlines()
|
||||
print("\n".join(lines[4:])) # remove '/removed/for/test/purposes.py'
|
||||
|
||||
|
||||
def main():
|
||||
print_test_error()
|
||||
|
||||
def patch(self, err, test):
|
||||
lines = better_exceptions.format_exception(*err)
|
||||
if sys.version_info[0] == 2:
|
||||
return u"".join(lines).encode("utf-8")
|
||||
else:
|
||||
return u"".join(lines)
|
||||
|
||||
unittest.result.TestResult._exc_info_to_string = patch
|
||||
|
||||
print_test_error()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -43,6 +43,7 @@ function test_all {
|
||||
test_case "$BETEXC_PYTHON" "test/test_truncating_disabled.py"
|
||||
test_case "$BETEXC_PYTHON" "test/test_indentation_error.py"
|
||||
test_case "$BETEXC_PYTHON" "test/test_syntax_error.py"
|
||||
test_case "$BETEXC_PYTHON" "test/test_unittest_patch.py"
|
||||
|
||||
if [[ "$BETEXC_PYTHON" == "python3" ]]; then
|
||||
test_case "$BETEXC_PYTHON" "test/test_chaining.py"
|
||||
|
Loading…
x
Reference in New Issue
Block a user