Compare commits
1046 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96784c2052 | ||
|
|
ebba3ebe67 | ||
|
|
1d09e1d8ce | ||
|
|
d59786fcc4 | ||
|
|
af34164858 | ||
|
|
167e9b954a | ||
|
|
9cde67c09c | ||
|
|
ae2fc27799 | ||
|
|
56989a8350 | ||
|
|
ce0b0518c7 | ||
|
|
bfa1993840 | ||
|
|
63691f5656 | ||
|
|
041044eef0 | ||
|
|
1af31a09f4 | ||
|
|
ccdb248397 | ||
|
|
2368fbb63c | ||
|
|
f6dfca7182 | ||
|
|
4a69104af3 | ||
|
|
2cf4c67e45 | ||
|
|
2ad43ee442 | ||
|
|
15278aacb9 | ||
|
|
57caa4e25e | ||
|
|
b6fa4e248f | ||
|
|
9df1b037d6 | ||
|
|
28dbffdaf2 | ||
|
|
8bced7415c | ||
|
|
72d98a7c52 | ||
|
|
0dd85157ea | ||
|
|
fadac0ffc0 | ||
|
|
799b72cf6f | ||
|
|
fc0f89ac14 | ||
|
|
771e860011 | ||
|
|
cb39bd0651 | ||
|
|
c94b2b227e | ||
|
|
cd72e23f3f | ||
|
|
b9990f77ff | ||
|
|
6b126997e1 | ||
|
|
02ae7d8531 | ||
|
|
db106d6085 | ||
|
|
b0eed7b56c | ||
|
|
51d358a7a9 | ||
|
|
c54cdd05b8 | ||
|
|
dde147641e | ||
|
|
2abd005cc9 | ||
|
|
366b88388b | ||
|
|
0fc1801d0d | ||
|
|
11ff14be1f | ||
|
|
dc0b4efffa | ||
|
|
864d7fef30 | ||
|
|
18035211f5 | ||
|
|
61080da89d | ||
|
|
ac5704290f | ||
|
|
cdd0e18ca8 | ||
|
|
e4871f7722 | ||
|
|
517ee588c6 | ||
|
|
1b51497936 | ||
|
|
a83ee197c6 | ||
|
|
12f94b81c0 | ||
|
|
e6b01b45f1 | ||
|
|
56dd7bc551 | ||
|
|
8a768b0db0 | ||
|
|
8dca8f3c9f | ||
|
|
cc335d44a0 | ||
|
|
4f4c91caf5 | ||
|
|
ba5a295544 | ||
|
|
93bdbf7572 | ||
|
|
ab8907f6f5 | ||
|
|
215a2ed3de | ||
|
|
f7285b6ab2 | ||
|
|
ee0a306ee4 | ||
|
|
7931b5b489 | ||
|
|
c5bbf8ac73 | ||
|
|
253c5786af | ||
|
|
c4550bc922 | ||
|
|
2c00f8aad1 | ||
|
|
456715a5c1 | ||
|
|
f858177495 | ||
|
|
54b8ad4554 | ||
|
|
d72154acda | ||
|
|
f55ded20a9 | ||
|
|
17655b54f2 | ||
|
|
12edc4e7b8 | ||
|
|
2868c31495 | ||
|
|
39a13d7064 | ||
|
|
e4e4fd1e52 | ||
|
|
e8c220b9bd | ||
|
|
9646a1cd7a | ||
|
|
9087ac4010 | ||
|
|
093e19a7d9 | ||
|
|
9e867ce864 | ||
|
|
8abf30ad71 | ||
|
|
ea25eb1ecc | ||
|
|
58b6e8616c | ||
|
|
f129ba617f | ||
|
|
99d957bd3d | ||
|
|
661013c3e9 | ||
|
|
141c51f0cb | ||
|
|
d65c7658d5 | ||
|
|
7855284ef7 | ||
|
|
5b0f88712b | ||
|
|
2e42d937dc | ||
|
|
27d932e882 | ||
|
|
40091ec2c7 | ||
|
|
76fb9970c8 | ||
|
|
d32f2c5c14 | ||
|
|
49defa2890 | ||
|
|
fe2dae4885 | ||
|
|
ced62f30ba | ||
|
|
bbd1cbb0b3 | ||
|
|
d4dfd526c1 | ||
|
|
d4351ac5a2 | ||
|
|
766d2daa06 | ||
|
|
836c9f82f1 | ||
|
|
46d6a3fc27 | ||
|
|
1dfa303b1e | ||
|
|
6258248865 | ||
|
|
4808145846 | ||
|
|
a0666354dd | ||
|
|
ce55dcf64c | ||
|
|
d7be039f1b | ||
|
|
7e1fac5f91 | ||
|
|
486ded3fca | ||
|
|
0be84cd68b | ||
|
|
323c846ce6 | ||
|
|
3bd9f981a2 | ||
|
|
7ded937e19 | ||
|
|
6d0667f1db | ||
|
|
7c380b19f3 | ||
|
|
5322f422e3 | ||
|
|
c6c326f076 | ||
|
|
d6832a8b56 | ||
|
|
3bfaa8ab84 | ||
|
|
9fb305b17b | ||
|
|
e3bf9cede4 | ||
|
|
4a49715614 | ||
|
|
86c7dcff68 | ||
|
|
7268462b33 | ||
|
|
448830e656 | ||
|
|
3683d92c53 | ||
|
|
d3d8d53e41 | ||
|
|
7a271a91b0 | ||
|
|
47f5c29002 | ||
|
|
27d2683a02 | ||
|
|
792f365c14 | ||
|
|
91b2797498 | ||
|
|
c27c8f41a8 | ||
|
|
ee54fb9a6b | ||
|
|
10ddc466bf | ||
|
|
24c83d725a | ||
|
|
6bf4692c7d | ||
|
|
81426c3d19 | ||
|
|
ed42ada373 | ||
|
|
e2667106a2 | ||
|
|
29d5849519 | ||
|
|
eabf15b626 | ||
|
|
2dc619cbf4 | ||
|
|
307fa7a42a | ||
|
|
ef97121d42 | ||
|
|
d46b6b2bc3 | ||
|
|
2cb3534679 | ||
|
|
8e11fe5304 | ||
|
|
36dc671843 | ||
|
|
dbaa9464ba | ||
|
|
933de16fe4 | ||
|
|
e8348a1d12 | ||
|
|
0f5263cdc3 | ||
|
|
4736b2bdfb | ||
|
|
8ecdd4e9ff | ||
|
|
b3940666a7 | ||
|
|
e20987ce82 | ||
|
|
584051aa90 | ||
|
|
16e2737da3 | ||
|
|
36c2a101cb | ||
|
|
ebd597b2fd | ||
|
|
94829c391b | ||
|
|
b82d6f7a0b | ||
|
|
4a436b5470 | ||
|
|
ad6f63edda | ||
|
|
3036914097 | ||
|
|
2831cb9ab5 | ||
|
|
00716177b4 | ||
|
|
85cc9b8f12 | ||
|
|
fed4f73a61 | ||
|
|
d76fa59b35 | ||
|
|
2532dc1dbb | ||
|
|
642cd86dd1 | ||
|
|
b3a5b0ebe1 | ||
|
|
8b4a29357e | ||
|
|
ab3637d486 | ||
|
|
66a690928c | ||
|
|
8e00280fc1 | ||
|
|
d053cdfbbb | ||
|
|
2e39fd89d1 | ||
|
|
b48e23d54c | ||
|
|
c9a85b0e78 | ||
|
|
bf265a424d | ||
|
|
5436e42990 | ||
|
|
67f40e18a7 | ||
|
|
52ff1eaf37 | ||
|
|
602e74c2a7 | ||
|
|
be511c1a05 | ||
|
|
f36f9d2698 | ||
|
|
dbfb3ccc42 | ||
|
|
d1322570dd | ||
|
|
4c9015c3b1 | ||
|
|
c14a23d4e4 | ||
|
|
b8fc3e569a | ||
|
|
e0f6fce9e9 | ||
|
|
d93de6cc67 | ||
|
|
aeb92accb2 | ||
|
|
943bbdd8ce | ||
|
|
9a3836a0cf | ||
|
|
4b164d947d | ||
|
|
11a07211b6 | ||
|
|
28a3f0fcb9 | ||
|
|
b8c30aab2b | ||
|
|
b8958168f5 | ||
|
|
aaaae0b232 | ||
|
|
c55d641963 | ||
|
|
4ec85f934c | ||
|
|
8393fdd51d | ||
|
|
4071c8a4a8 | ||
|
|
e8c10d4a98 | ||
|
|
a86035625c | ||
|
|
4f631440be | ||
|
|
3901569f26 | ||
|
|
689b856cb7 | ||
|
|
65545d8fb2 | ||
|
|
1caf6d5907 | ||
|
|
55871c68a4 | ||
|
|
fc11b81005 | ||
|
|
a6fb4c8268 | ||
|
|
48dcc67274 | ||
|
|
ccaec8d360 | ||
|
|
66609665f2 | ||
|
|
4b36f9aa64 | ||
|
|
5ecbb0acba | ||
|
|
20902deb75 | ||
|
|
ed5556bdac | ||
|
|
ee64f1fb9f | ||
|
|
8e0e862c84 | ||
|
|
42422a7f62 | ||
|
|
f3a173b736 | ||
|
|
5c38a5160d | ||
|
|
dcf9eb0104 | ||
|
|
dd225e1b9d | ||
|
|
900cef6397 | ||
|
|
0d095fc978 | ||
|
|
dcd635ba0c | ||
|
|
33f0338eeb | ||
|
|
d5e5433553 | ||
|
|
d2906950ce | ||
|
|
fe7050ba00 | ||
|
|
a1208f5631 | ||
|
|
870a93c37b | ||
|
|
96b2ae6654 | ||
|
|
b098292352 | ||
|
|
212937eb3e | ||
|
|
70c7273640 | ||
|
|
e5ab62b1b6 | ||
|
|
b8b9e8d41c | ||
|
|
e712adc226 | ||
|
|
f9ac60807c | ||
|
|
3f03625a5d | ||
|
|
29d3faed66 | ||
|
|
c5dec6056f | ||
|
|
642847c079 | ||
|
|
f102ccc8f0 | ||
|
|
20f93ae8fa | ||
|
|
1101a20408 | ||
|
|
df435fa8bd | ||
|
|
a5269b26e0 | ||
|
|
d3673c7429 | ||
|
|
5010e02eda | ||
|
|
25fe3706a4 | ||
|
|
1a323fbd3c | ||
|
|
9d971d33be | ||
|
|
bc009a8582 | ||
|
|
5e7d427df1 | ||
|
|
dd59ed3b18 | ||
|
|
20d0f0e56b | ||
|
|
d24a7e6c5a | ||
|
|
4dc73bda45 | ||
|
|
732cc2687d | ||
|
|
5d2d64c190 | ||
|
|
7a6d16c1eb | ||
|
|
c2179c3127 | ||
|
|
d8d7f73e1c | ||
|
|
3c23b5b010 | ||
|
|
783019a8e6 | ||
|
|
d2fc7ca6e0 | ||
|
|
2d06927a06 | ||
|
|
44d29d887e | ||
|
|
32c5a113e2 | ||
|
|
ba5630e0f8 | ||
|
|
808df48ee8 | ||
|
|
a089a9577e | ||
|
|
6be2136f20 | ||
|
|
f9ab81a493 | ||
|
|
1636522563 | ||
|
|
b1fbb2ab92 | ||
|
|
e85edf5212 | ||
|
|
b03bad5dbb | ||
|
|
19ec300b2a | ||
|
|
11442f2ad7 | ||
|
|
97748b6605 | ||
|
|
2b762337bd | ||
|
|
9899b8f1fb | ||
|
|
956b3aca97 | ||
|
|
4474beeb82 | ||
|
|
5d8467bedc | ||
|
|
eca3e781b6 | ||
|
|
0d04aa7c59 | ||
|
|
c61ff31ffa | ||
|
|
e03a19f88d | ||
|
|
fcc5b6d604 | ||
|
|
42afce27b3 | ||
|
|
56d0b5a7e2 | ||
|
|
ec57cbf82d | ||
|
|
3f6a46c2a4 | ||
|
|
c30184709d | ||
|
|
4ba3cb25b0 | ||
|
|
650c458df9 | ||
|
|
58aa4f91f5 | ||
|
|
9b382ed16c | ||
|
|
f02dbaf97f | ||
|
|
41f6ea13ce | ||
|
|
f6eb39df33 | ||
|
|
7a5e11bbcf | ||
|
|
7122fa5613 | ||
|
|
7aff81739e | ||
|
|
27772f67c0 | ||
|
|
10b3b2dc68 | ||
|
|
c2841542af | ||
|
|
1f28096587 | ||
|
|
e86b01e831 | ||
|
|
83802d1494 | ||
|
|
d1fa8ae08e | ||
|
|
29dac03314 | ||
|
|
e7eb7e799b | ||
|
|
18cc74b8d0 | ||
|
|
7f48f552c1 | ||
|
|
1e2e65f0fa | ||
|
|
28c9cc7321 | ||
|
|
ccb90b5c46 | ||
|
|
048342817b | ||
|
|
d1a3aa7b2b | ||
|
|
e967d4587a | ||
|
|
a79dc12f1e | ||
|
|
37d2469266 | ||
|
|
1df6d28080 | ||
|
|
03eaad376b | ||
|
|
739f9a4a4b | ||
|
|
93224f8cf9 | ||
|
|
bb57186dd4 | ||
|
|
2803eb9fbb | ||
|
|
913c07e414 | ||
|
|
4a9f468aac | ||
|
|
05155e4db0 | ||
|
|
f53eff93db | ||
|
|
bceaede198 | ||
|
|
86a14d007d | ||
|
|
a4dd6ee3ce | ||
|
|
130cf7e0db | ||
|
|
cbb41f1ae2 | ||
|
|
fa78da3c03 | ||
|
|
ae8f3695b5 | ||
|
|
87ddb2dbd5 | ||
|
|
9aa6b0903b | ||
|
|
da6830f19b | ||
|
|
32ee0b9c88 | ||
|
|
49800ea134 | ||
|
|
feb8240410 | ||
|
|
b7dd9154c3 | ||
|
|
482bd5efd2 | ||
|
|
bf074b37a3 | ||
|
|
495a55725b | ||
|
|
53c9124fc9 | ||
|
|
8fe55b1d18 | ||
|
|
a0ce9a4441 | ||
|
|
2cf2dc3d95 | ||
|
|
7537e94ddf | ||
|
|
ab40696007 | ||
|
|
2c90b3db9e | ||
|
|
826adafe2e | ||
|
|
3dd2933dbd | ||
|
|
d12f46caef | ||
|
|
b55351274e | ||
|
|
c00d934b21 | ||
|
|
6b526cbe6a | ||
|
|
e0539e6ede | ||
|
|
5eb85efa14 | ||
|
|
9ee8d72fd2 | ||
|
|
8c4ca383ca | ||
|
|
f2a427da25 | ||
|
|
e0466d0ad8 | ||
|
|
418a66a09f | ||
|
|
5e2bd17d18 | ||
|
|
ec6fca4aa7 | ||
|
|
1f20626618 | ||
|
|
69b34f7658 | ||
|
|
531b76a513 | ||
|
|
f63c683faa | ||
|
|
410d5762c0 | ||
|
|
ddb308455a | ||
|
|
f42b5019ec | ||
|
|
adc9ed85bc | ||
|
|
4592def14d | ||
|
|
2e0a7cf78d | ||
|
|
5a52acaa92 | ||
|
|
6d497f2c77 | ||
|
|
b7560a8808 | ||
|
|
d3ca739c00 | ||
|
|
3db76ccf3d | ||
|
|
438f7a1254 | ||
|
|
47bf58d69e | ||
|
|
5ef51262f7 | ||
|
|
a054aa4797 | ||
|
|
f1cfd10c94 | ||
|
|
d3f72ca202 | ||
|
|
022c58bf64 | ||
|
|
b42518acd5 | ||
|
|
284a2d110f | ||
|
|
9ae0a3cd85 | ||
|
|
615c671434 | ||
|
|
29bfa5efa4 | ||
|
|
016f8f1536 | ||
|
|
e9417be9df | ||
|
|
c304998ed7 | ||
|
|
415a62e373 | ||
|
|
8ce3aeadbf | ||
|
|
b818314045 | ||
|
|
56d414177a | ||
|
|
0fffa6ba2f | ||
|
|
60499d221e | ||
|
|
9965ed84da | ||
|
|
7e13593452 | ||
|
|
208dd3aad1 | ||
|
|
19a01c9849 | ||
|
|
78ac7d99f5 | ||
|
|
0c8dbdcd92 | ||
|
|
8e4501ee29 | ||
|
|
0100f61b62 | ||
|
|
1a9d913ee1 | ||
|
|
51e32cf7cc | ||
|
|
3fcc4cdbd5 | ||
|
|
ffd47ceefc | ||
|
|
10f21b423a | ||
|
|
eec7081b8d | ||
|
|
b01704cce1 | ||
|
|
15ede8aab8 | ||
|
|
f7dc9b9fef | ||
|
|
dc13f0b469 | ||
|
|
a13c6a84df | ||
|
|
dfa713163a | ||
|
|
90c00dfd54 | ||
|
|
f3b9b21996 | ||
|
|
885b8a3b4c | ||
|
|
4675912d89 | ||
|
|
495b44198f | ||
|
|
8d8e68cf90 | ||
|
|
f3b0caf299 | ||
|
|
75d29acc06 | ||
|
|
cbbb36fc9b | ||
|
|
d53e449296 | ||
|
|
01df368d93 | ||
|
|
2256f2f04d | ||
|
|
95881c870e | ||
|
|
019e33ee3f | ||
|
|
19fa01b91d | ||
|
|
96aad2983b | ||
|
|
c18a5b5179 | ||
|
|
ed4b94a180 | ||
|
|
29c5ac71bc | ||
|
|
84a9f7a263 | ||
|
|
11e591e442 | ||
|
|
64f00683f2 | ||
|
|
84a033fd97 | ||
|
|
0183d46275 | ||
|
|
9bd4b0a05e | ||
|
|
f0e852b4db | ||
|
|
ade01b1f5b | ||
|
|
3035b2724d | ||
|
|
8c96eea583 | ||
|
|
338953a25d | ||
|
|
f1bd46266b | ||
|
|
77cad3c436 | ||
|
|
3ca70692de | ||
|
|
417516c378 | ||
|
|
f730291e67 | ||
|
|
d76fb8345c | ||
|
|
aea962dc21 | ||
|
|
4345efaffc | ||
|
|
bf47033169 | ||
|
|
37a65684d6 | ||
|
|
eab5020e24 | ||
|
|
8ef21f56d3 | ||
|
|
103d980b2d | ||
|
|
28c3ef1c77 | ||
|
|
67c3c28877 | ||
|
|
e040fd20a3 | ||
|
|
00e0b43010 | ||
|
|
f19cfbb825 | ||
|
|
bde3d1a0cd | ||
|
|
2e090896d5 | ||
|
|
b0a32da0b5 | ||
|
|
10c1c7c41a | ||
|
|
16f452ef98 | ||
|
|
b77e533693 | ||
|
|
a605ad4d11 | ||
|
|
4b94760c8e | ||
|
|
82a7ca9615 | ||
|
|
23295e1e98 | ||
|
|
32575f92c9 | ||
|
|
a260e58020 | ||
|
|
b2f7e02a02 | ||
|
|
29e114b463 | ||
|
|
2a059b1c1b | ||
|
|
cdc72bf5a3 | ||
|
|
f786335dbb | ||
|
|
ab5af524a4 | ||
|
|
9620b167d9 | ||
|
|
8f4685e024 | ||
|
|
10544c4cb8 | ||
|
|
1e8e17c01e | ||
|
|
80eef29681 | ||
|
|
47bb53f5cb | ||
|
|
6991a16edb | ||
|
|
2f2d5861bb | ||
|
|
a31967431f | ||
|
|
e74ad4ff9b | ||
|
|
70bdacf01a | ||
|
|
b69f853acb | ||
|
|
c31018d9bc | ||
|
|
7ae23901d3 | ||
|
|
4d19b94347 | ||
|
|
c15b537e3d | ||
|
|
2577a6ce8a | ||
|
|
dd5f5ca4cb | ||
|
|
508774742e | ||
|
|
2a917a582e | ||
|
|
325319dc3b | ||
|
|
dda5e5ea32 | ||
|
|
5e260c4d34 | ||
|
|
d3f5324386 | ||
|
|
3da88d794f | ||
|
|
71b4995775 | ||
|
|
b0541e9d31 | ||
|
|
415fcb912b | ||
|
|
f872fcb5d0 | ||
|
|
de6f2c0336 | ||
|
|
be4b359c74 | ||
|
|
72a58bbafe | ||
|
|
c336449729 | ||
|
|
1e4ecda884 | ||
|
|
8cf0e46bbf | ||
|
|
f0226e9329 | ||
|
|
dce8df45d5 | ||
|
|
f6948597e4 | ||
|
|
e3df1031ca | ||
|
|
14ffadf004 | ||
|
|
459b040d21 | ||
|
|
3396225f74 | ||
|
|
c82906105c | ||
|
|
4c14740798 | ||
|
|
5fefc48f33 | ||
|
|
72e6482994 | ||
|
|
93f783228c | ||
|
|
5f8b50c094 | ||
|
|
99e31f6fb1 | ||
|
|
f2e35c8c4f | ||
|
|
40b4fe64af | ||
|
|
d10d59c013 | ||
|
|
d54aa8ce13 | ||
|
|
52fa8c98bb | ||
|
|
3f336869e2 | ||
|
|
85482d575e | ||
|
|
6f7365509d | ||
|
|
7099ea9bb0 | ||
|
|
dccac69d82 | ||
|
|
c2cd337886 | ||
|
|
0fc4a806e5 | ||
|
|
4d3c1ab4f0 | ||
|
|
e4f76f6350 | ||
|
|
0d65783dce | ||
|
|
8bb8b91357 | ||
|
|
8804c7333a | ||
|
|
17eec5b97e | ||
|
|
cd07c4d4ff | ||
|
|
917b99e438 | ||
|
|
b08e156b79 | ||
|
|
8e2c7b4979 | ||
|
|
5a7aa123ea | ||
|
|
a12eadd9ef | ||
|
|
2137e2b15b | ||
|
|
89446af51e | ||
|
|
3b521bedf8 | ||
|
|
5b2c8fa007 | ||
|
|
eb8d145195 | ||
|
|
80bea79512 | ||
|
|
07a560ff24 | ||
|
|
717775a1c6 | ||
|
|
672f4bb5aa | ||
|
|
f1079a8222 | ||
|
|
044d2b8e6e | ||
|
|
223eef6261 | ||
|
|
43657f252f | ||
|
|
70ebab3537 | ||
|
|
d3bdfc704b | ||
|
|
4de247cfa0 | ||
|
|
d611b03589 | ||
|
|
308d789d92 | ||
|
|
539a22c750 | ||
|
|
e4bea9068b | ||
|
|
e620798d33 | ||
|
|
7ea4992f16 | ||
|
|
0564b52c0e | ||
|
|
8b2c91836b | ||
|
|
9e382e8d29 | ||
|
|
2255892d65 | ||
|
|
7d9b198f73 | ||
|
|
a6cdd0d9da | ||
|
|
c64a8c9c7f | ||
|
|
f4c5994d27 | ||
|
|
c24c7e75e2 | ||
|
|
273670b2a2 | ||
|
|
28aff051ab | ||
|
|
29975e5b37 | ||
|
|
5cf7d1dba2 | ||
|
|
2fe824b8c4 | ||
|
|
f674217c43 | ||
|
|
9f7345d663 | ||
|
|
eb2d074530 | ||
|
|
9fa7745795 | ||
|
|
14db2f91ba | ||
|
|
c3e494f6cf | ||
|
|
090f67a980 | ||
|
|
3059bfb1b3 | ||
|
|
e391c47ed8 | ||
|
|
f66764e1c0 | ||
|
|
e0b088b52e | ||
|
|
e5a3c870b4 | ||
|
|
2b71cb9c38 | ||
|
|
da9d814da4 | ||
|
|
7d4c4c66d4 | ||
|
|
939a792c41 | ||
|
|
17644ff285 | ||
|
|
64faa41d06 | ||
|
|
ca1bb9a3a1 | ||
|
|
78ef531420 | ||
|
|
212ee450b7 | ||
|
|
c1c08852f9 | ||
|
|
e06a077ac2 | ||
|
|
cb77e65c97 | ||
|
|
6367f0f5f1 | ||
|
|
b88e09a697 | ||
|
|
68bbd42213 | ||
|
|
22ee2093b8 | ||
|
|
87a99275fb | ||
|
|
abbd7c30a4 | ||
|
|
abae60c8d0 | ||
|
|
e92893ed24 | ||
|
|
27b5435a40 | ||
|
|
50db718a6a | ||
|
|
bfd0addaeb | ||
|
|
be11d3e195 | ||
|
|
266f05c4c4 | ||
|
|
d0bd01beca | ||
|
|
220288ac77 | ||
|
|
4d8903fd0b | ||
|
|
67106f056b | ||
|
|
5d3c5123f8 | ||
|
|
5f97711377 | ||
|
|
74d9f56d0f | ||
|
|
051db6a33d | ||
|
|
aa358433b0 | ||
|
|
126896f69d | ||
|
|
e723069165 | ||
|
|
855fd17014 | ||
|
|
d11781920b | ||
|
|
2c0d2eef40 | ||
|
|
ef8ec01e39 | ||
|
|
0a1c2a7ca1 | ||
|
|
fe0a76e1a6 | ||
|
|
dcafb8c48c | ||
|
|
a76cc8f8c4 | ||
|
|
4d2fa581e1 | ||
|
|
f7a3f45a18 | ||
|
|
dff7b203f7 | ||
|
|
4705fd2bbe | ||
|
|
ca0476953e | ||
|
|
7e92930fa9 | ||
|
|
33769d0328 | ||
|
|
5db2e6c7a1 | ||
|
|
804fc4063a | ||
|
|
82a2174867 | ||
|
|
a80e031c62 | ||
|
|
452e5c1cf0 | ||
|
|
c6b11b9f62 | ||
|
|
b8255308d6 | ||
|
|
a5c0fb7f6b | ||
|
|
f25683354e | ||
|
|
7d13599ba1 | ||
|
|
43664d7841 | ||
|
|
2a2f888909 | ||
|
|
ad5ddaf55a | ||
|
|
4588130c1e | ||
|
|
5003bae0de | ||
|
|
6e32a1f73d | ||
|
|
611d254ed5 | ||
|
|
57a8f208bc | ||
|
|
fcdc1d867e | ||
|
|
098dca3a9f | ||
|
|
8e2ed76227 | ||
|
|
bf7c188cc0 | ||
|
|
8c9efd8608 | ||
|
|
e1ad1a14af | ||
|
|
327fe4cfcc | ||
|
|
d02491931a | ||
|
|
032db159c9 | ||
|
|
cd2085ee71 | ||
|
|
ad305e71d7 | ||
|
|
7d8688d54b | ||
|
|
253419316c | ||
|
|
997ef59306 | ||
|
|
60b1913ba2 | ||
|
|
2c09930b6d | ||
|
|
d461e931dd | ||
|
|
eada0b1fd7 | ||
|
|
150535b6c1 | ||
|
|
f1ec02cdcd | ||
|
|
9f5d73d44a | ||
|
|
8609f8d25a | ||
|
|
953a618102 | ||
|
|
cf6d8e7e53 | ||
|
|
8af78f417f | ||
|
|
535fd1f311 | ||
|
|
762eaf443a | ||
|
|
330640eb96 | ||
|
|
e3d412d1f4 | ||
|
|
6f9a12a8a3 | ||
|
|
0e47599572 | ||
|
|
c480223e88 | ||
|
|
0b522d40a7 | ||
|
|
d900a6c8bd | ||
|
|
fe46fbb719 | ||
|
|
8d401cdb9d | ||
|
|
3f3f6f1be4 | ||
|
|
b6da5cc54c | ||
|
|
eaeeedc9c3 | ||
|
|
317cd41215 | ||
|
|
7f27512a48 | ||
|
|
bf127a63b2 | ||
|
|
fe16f81da1 | ||
|
|
d0ba242c46 | ||
|
|
fe06be8590 | ||
|
|
79b4ca92d8 | ||
|
|
57b0c60cb4 | ||
|
|
6e57d123bb | ||
|
|
011f88f7e7 | ||
|
|
2eb9301ad5 | ||
|
|
f0db64ac2e | ||
|
|
514ca6f4ad | ||
|
|
b7419bd9bb | ||
|
|
2e344d4d63 | ||
|
|
f8749eeb5c | ||
|
|
f76142508f | ||
|
|
be2afb950a | ||
|
|
19de1b7f29 | ||
|
|
f5165064ee | ||
|
|
c9a0881309 | ||
|
|
5167933395 | ||
|
|
75db608479 | ||
|
|
7bff5866b1 | ||
|
|
9720c3301a | ||
|
|
254689ff83 | ||
|
|
21f5222784 | ||
|
|
0bb29d5649 | ||
|
|
db33f03c15 | ||
|
|
ac9ceaacd8 | ||
|
|
771d3e8f4f | ||
|
|
82a11e6207 | ||
|
|
a1c3df1889 | ||
|
|
a821af6b1c | ||
|
|
d2fe619120 | ||
|
|
58e77f58bd | ||
|
|
6a4fa4f485 | ||
|
|
5be03bff61 | ||
|
|
e9fd038aae | ||
|
|
a8464a95ce | ||
|
|
a0b0c37feb | ||
|
|
35ffd29404 | ||
|
|
0565a7a4e1 | ||
|
|
6c3713226c | ||
|
|
f6ceedd15b | ||
|
|
3e599dc149 | ||
|
|
54fbc6f6e1 | ||
|
|
aa47b64e2a | ||
|
|
251adbf644 | ||
|
|
2c4759ce57 | ||
|
|
4dfe2eee94 | ||
|
|
5226c7fac3 | ||
|
|
593b451373 | ||
|
|
898544e147 | ||
|
|
61301d934e | ||
|
|
af0059079c | ||
|
|
9ef7878cbc | ||
|
|
4ae93a7a07 | ||
|
|
d4faa4056b | ||
|
|
42bbb4fa8a | ||
|
|
12c5b6104c | ||
|
|
aa9d1ad2eb | ||
|
|
49e82a4be8 | ||
|
|
803302e70c | ||
|
|
05f1d0d3ef | ||
|
|
1cd62f8c38 | ||
|
|
a522fc745a | ||
|
|
303133f013 | ||
|
|
d26a596072 | ||
|
|
f359b50fe5 | ||
|
|
18b2fc11ad | ||
|
|
d7b722e2ae | ||
|
|
1e94ac784f | ||
|
|
027d2336b8 | ||
|
|
3c19370cec | ||
|
|
7e8f7bfa16 | ||
|
|
3f5e06ecc4 | ||
|
|
50f030d233 | ||
|
|
7696d5371a | ||
|
|
b64c26674d | ||
|
|
63b25304c3 | ||
|
|
73d787df3a | ||
|
|
fa3161011a | ||
|
|
2921ca6e64 | ||
|
|
43c0346d68 | ||
|
|
3ed8e28ef3 | ||
|
|
b84a646389 | ||
|
|
8232fd1a2d | ||
|
|
f52a5d3be2 | ||
|
|
b815f67e65 | ||
|
|
55ebf261ce | ||
|
|
067de257e1 | ||
|
|
4a925ef5e9 | ||
|
|
4afb8c428b | ||
|
|
2f1a2cf07f | ||
|
|
6cc4fe2412 | ||
|
|
10a8691eca | ||
|
|
b75320ba95 | ||
|
|
b50911285a | ||
|
|
a43205b4bc | ||
|
|
bc268a58d1 | ||
|
|
0b70477930 | ||
|
|
8801162275 | ||
|
|
a604a71185 | ||
|
|
66fa6bb42e | ||
|
|
713d32c4da | ||
|
|
57198d477b | ||
|
|
533f4cc10c | ||
|
|
a46b94950c | ||
|
|
952bbefaac | ||
|
|
54d3cd587d | ||
|
|
2b75a311a7 | ||
|
|
26e1784e52 | ||
|
|
dad3e77319 | ||
|
|
3a1c15316b | ||
|
|
f7c929c932 | ||
|
|
b48f1d378b | ||
|
|
a6636fddcd | ||
|
|
738933938a | ||
|
|
342f2cdc17 | ||
|
|
5bd5b8c68a | ||
|
|
0fd86ec8a8 | ||
|
|
4ae7e9788c | ||
|
|
5582ad0445 | ||
|
|
982b614010 | ||
|
|
7845ab4bc3 | ||
|
|
8680dfc939 | ||
|
|
76ac670f7d | ||
|
|
7b47dfb744 | ||
|
|
3c73d6298a | ||
|
|
c220fb235a | ||
|
|
1dc5e97ac2 | ||
|
|
e9371a58a0 | ||
|
|
a48c47b53b | ||
|
|
ea379ba10f | ||
|
|
9a56bb05be | ||
|
|
17e01993d9 | ||
|
|
8a6345515b | ||
|
|
581d49635e | ||
|
|
ef1b91ba87 | ||
|
|
e860ff7299 | ||
|
|
0672bc633f | ||
|
|
2dfb52f7e0 | ||
|
|
cc6eb9f83c | ||
|
|
643e5a9c44 | ||
|
|
b8486037d3 | ||
|
|
78a82c05ef | ||
|
|
853975d93b | ||
|
|
6b239263da | ||
|
|
89e0a3ec27 | ||
|
|
f93995e15c | ||
|
|
f940967e23 | ||
|
|
cbaa7dd56a | ||
|
|
8133d1955e | ||
|
|
738b715655 | ||
|
|
1d5316a28b | ||
|
|
0030ceb11c | ||
|
|
5b186cd609 | ||
|
|
5a156b3645 | ||
|
|
42b3125783 | ||
|
|
50a0d4fa95 | ||
|
|
deff54aae0 | ||
|
|
22a2734d9a | ||
|
|
17985b893d | ||
|
|
1d55c49a9a | ||
|
|
95f00de0df | ||
|
|
c4c666cbc4 | ||
|
|
ee30bf45c9 | ||
|
|
603df1ea1c | ||
|
|
abbf73ad1a | ||
|
|
1226cdab47 | ||
|
|
ab80e0fba0 | ||
|
|
fb992a0c81 | ||
|
|
23581d44bd | ||
|
|
c7eb53317b | ||
|
|
8cc210708c | ||
|
|
4970f6d5c2 | ||
|
|
f883628939 | ||
|
|
40839b5a3a | ||
|
|
5e56d77542 | ||
|
|
de98939ebf | ||
|
|
0d3914b626 | ||
|
|
eb94bce3e2 | ||
|
|
b897008887 | ||
|
|
630428c611 | ||
|
|
8b4c59e606 | ||
|
|
998d540b73 | ||
|
|
c672bfa32e | ||
|
|
8f1d8ac970 | ||
|
|
1ac1ee6fcb | ||
|
|
53d4710c62 | ||
|
|
31f089db6a | ||
|
|
b7b9c54d27 | ||
|
|
e86fe38144 | ||
|
|
5b26178397 | ||
|
|
130100bba1 | ||
|
|
46aa18dfa7 | ||
|
|
617a5fcf98 | ||
|
|
19ba243cae | ||
|
|
af5d41fdfd | ||
|
|
85be8bdf49 | ||
|
|
8e9f1d2417 | ||
|
|
93e55ad2fa | ||
|
|
2925f3057f | ||
|
|
a93ad1fb77 | ||
|
|
561db95521 | ||
|
|
9408291c50 | ||
|
|
4dc7b4ace6 | ||
|
|
acb8f23311 | ||
|
|
9d60cf25c0 | ||
|
|
9e32b6ae48 | ||
|
|
99402cf1c0 | ||
|
|
b285078db4 | ||
|
|
d382f3e77f | ||
|
|
5221a14764 | ||
|
|
3ac2ae3c8c | ||
|
|
ea906056fa | ||
|
|
c081c5ee23 | ||
|
|
3dcdaab103 | ||
|
|
3615977608 | ||
|
|
94c41bec64 | ||
|
|
8d072205e9 | ||
|
|
b5102d03a6 | ||
|
|
791bb3502c | ||
|
|
eb0c6a8287 | ||
|
|
4d0297b413 | ||
|
|
88ae21f2cc | ||
|
|
321f66f711 | ||
|
|
52c4279918 | ||
|
|
077c44cf69 | ||
|
|
f786534173 | ||
|
|
b0ec442d24 | ||
|
|
9a7c3a65f4 | ||
|
|
37793d4cdb | ||
|
|
1b5322da1b | ||
|
|
d6e7b1a21b | ||
|
|
4983de60d3 | ||
|
|
e0a1da4eb9 | ||
|
|
ef88251573 | ||
|
|
f300f7fa24 | ||
|
|
41125968d9 | ||
|
|
4fd66e8a42 | ||
|
|
a888bf182e | ||
|
|
04b65cfba0 | ||
|
|
61471df8da | ||
|
|
1aba123ac5 | ||
|
|
efc9a0ecb5 | ||
|
|
4a78711067 | ||
|
|
5ea647a245 | ||
|
|
11705040ac | ||
|
|
fe81de6150 | ||
|
|
49f621de76 | ||
|
|
10b0b81346 | ||
|
|
80f8a3ad7c | ||
|
|
198e993969 | ||
|
|
1a7dcd73cf | ||
|
|
7c8d072241 | ||
|
|
c4f72e4d13 | ||
|
|
3667a52ba2 | ||
|
|
97d48ba60d | ||
|
|
55bbd3e3e2 | ||
|
|
4c01dd651e | ||
|
|
472354c714 | ||
|
|
c1d9ca81df | ||
|
|
f389a4e91f | ||
|
|
942d363c03 | ||
|
|
c30c137a95 | ||
|
|
18157659ca | ||
|
|
60b34ec7ec | ||
|
|
60273d7e99 | ||
|
|
d694290626 | ||
|
|
56b3a9eb8f | ||
|
|
464117b472 | ||
|
|
1459cbe01f | ||
|
|
c9df77cbd6 | ||
|
|
026cd36237 | ||
|
|
bc2247219f | ||
|
|
9ddd573774 | ||
|
|
f99da9058f | ||
|
|
7d0dba18de | ||
|
|
6fc7f07a80 | ||
|
|
05b5b64379 | ||
|
|
229c8e551d | ||
|
|
d483b401ee | ||
|
|
acacf75f49 | ||
|
|
f8350c6304 | ||
|
|
fedc78522b | ||
|
|
b0474398ec | ||
|
|
dc90c9108f | ||
|
|
69031d0033 | ||
|
|
e44d4e6508 | ||
|
|
c416b1d935 | ||
|
|
7d923c389e | ||
|
|
c02e8d8b0d | ||
|
|
35df2cdbee | ||
|
|
2b1410895e |
11
.coveragerc
11
.coveragerc
@@ -1,4 +1,9 @@
|
||||
[run]
|
||||
omit =
|
||||
# standlonetemplate is read dynamically and tested by test_genscript
|
||||
*standalonetemplate.py
|
||||
source = pytest,_pytest,testing/
|
||||
parallel = 1
|
||||
branch = 1
|
||||
|
||||
[paths]
|
||||
source = src/
|
||||
.tox/*/lib/python*/site-packages/
|
||||
.tox\*\Lib\site-packages\
|
||||
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1 +1 @@
|
||||
CHANGELOG merge=union
|
||||
*.bat text eol=crlf
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -3,7 +3,7 @@ Thanks for submitting a PR, your contribution is really appreciated!
|
||||
Here's a quick checklist that should be present in PRs (you can delete this text from the final description, this is
|
||||
just a guideline):
|
||||
|
||||
- [ ] Create a new changelog file in the `changelog` folder, with a name like `<ISSUE NUMBER>.<TYPE>.rst`. See [changelog/README.rst](/changelog/README.rst) for details.
|
||||
- [ ] Create a new changelog file in the `changelog` folder, with a name like `<ISSUE NUMBER>.<TYPE>.rst`. See [changelog/README.rst](https://github.com/pytest-dev/pytest/blob/master/changelog/README.rst) for details.
|
||||
- [ ] Target the `master` branch for bug fixes, documentation updates and trivial changes.
|
||||
- [ ] Target the `features` branch for new features and removals/deprecations.
|
||||
- [ ] Include documentation when adding new features.
|
||||
|
||||
149
.github/labels.toml
vendored
Normal file
149
.github/labels.toml
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
["os: cygwin"]
|
||||
color = "006b75"
|
||||
description = "cygwin platform-specific problem"
|
||||
name = "os: cygwin"
|
||||
|
||||
["os: linux"]
|
||||
color = "1d76db"
|
||||
description = "linux platform-specific problem"
|
||||
name = "os: linux"
|
||||
|
||||
["os: mac"]
|
||||
color = "bfdadc"
|
||||
description = "mac platform-specific problem"
|
||||
name = "os: mac"
|
||||
|
||||
["os: windows"]
|
||||
color = "fbca04"
|
||||
description = "windows platform-specific problem"
|
||||
name = "os: windows"
|
||||
|
||||
["plugin: argcomplete"]
|
||||
color = "d4c5f9"
|
||||
description = "related to the argcomplete builtin plugin"
|
||||
name = "plugin: argcomplete"
|
||||
|
||||
["plugin: cache"]
|
||||
color = "c7def8"
|
||||
description = "related to the cache builtin plugin"
|
||||
name = "plugin: cache"
|
||||
|
||||
["plugin: capture"]
|
||||
color = "1d76db"
|
||||
description = "related to the capture builtin plugin"
|
||||
name = "plugin: capture"
|
||||
|
||||
["plugin: debugging"]
|
||||
color = "dd52a8"
|
||||
description = "related to the debugging builtin plugin"
|
||||
name = "plugin: debugging"
|
||||
|
||||
["plugin: doctests"]
|
||||
color = "fad8c7"
|
||||
description = "related to the doctests builtin plugin"
|
||||
name = "plugin: doctests"
|
||||
|
||||
["plugin: junitxml"]
|
||||
color = "c5def5"
|
||||
description = "related to the junitxml builtin plugin"
|
||||
name = "plugin: junitxml"
|
||||
|
||||
["plugin: logging"]
|
||||
color = "ff5432"
|
||||
description = "related to the logging builtin plugin"
|
||||
name = "plugin: logging"
|
||||
|
||||
["plugin: monkeypatch"]
|
||||
color = "0e8a16"
|
||||
description = "related to the monkeypatch builtin plugin"
|
||||
name = "plugin: monkeypatch"
|
||||
|
||||
["plugin: nose"]
|
||||
color = "bfdadc"
|
||||
description = "related to the nose integration builtin plugin"
|
||||
name = "plugin: nose"
|
||||
|
||||
["plugin: pastebin"]
|
||||
color = "bfd4f2"
|
||||
description = "related to the pastebin builtin plugin"
|
||||
name = "plugin: pastebin"
|
||||
|
||||
["plugin: pytester"]
|
||||
color = "c5def5"
|
||||
description = "related to the pytester builtin plugin"
|
||||
name = "plugin: pytester"
|
||||
|
||||
["plugin: tmpdir"]
|
||||
color = "bfd4f2"
|
||||
description = "related to the tmpdir builtin plugin"
|
||||
name = "plugin: tmpdir"
|
||||
|
||||
["plugin: unittest"]
|
||||
color = "006b75"
|
||||
description = "related to the unittest integration builtin plugin"
|
||||
name = "plugin: unittest"
|
||||
|
||||
["plugin: warnings"]
|
||||
color = "fef2c0"
|
||||
description = "related to the warnings builtin plugin"
|
||||
name = "plugin: warnings"
|
||||
|
||||
["plugin: xdist"]
|
||||
color = "5319e7"
|
||||
description = "related to the xdist external plugin"
|
||||
name = "plugin: xdist"
|
||||
|
||||
["status: critical"]
|
||||
color = "e11d21"
|
||||
description = "grave problem or usability issue that affects lots of users"
|
||||
name = "status: critical"
|
||||
|
||||
["status: easy"]
|
||||
color = "bfe5bf"
|
||||
description = "easy issue that is friendly to new contributor"
|
||||
name = "status: easy"
|
||||
|
||||
["status: help wanted"]
|
||||
color = "159818"
|
||||
description = "developers would like help from experts on this topic"
|
||||
name = "status: help wanted"
|
||||
|
||||
["status: needs information"]
|
||||
color = "5319e7"
|
||||
description = "reporter needs to provide more information; can be closed after 2 or more weeks of inactivity"
|
||||
name = "status: needs information"
|
||||
|
||||
["topic: collection"]
|
||||
color = "006b75"
|
||||
description = "related to the collection phase"
|
||||
name = "topic: collection"
|
||||
|
||||
["topic: config"]
|
||||
color = "006b75"
|
||||
description = "related to config handling, argument parsing and config file"
|
||||
name = "topic: config"
|
||||
|
||||
["topic: fixtures"]
|
||||
color = "5319e7"
|
||||
description = "anything involving fixtures directly or indirectly"
|
||||
name = "topic: fixtures"
|
||||
|
||||
["topic: marks"]
|
||||
color = "b60205"
|
||||
description = "related to marks, either the general marks or builtin"
|
||||
name = "topic: marks"
|
||||
|
||||
["topic: parametrize"]
|
||||
color = "fbca04"
|
||||
description = "related to @pytest.mark.parametrize"
|
||||
name = "topic: parametrize"
|
||||
|
||||
["topic: reporting"]
|
||||
color = "fef2c0"
|
||||
description = "related to terminal output and user-facing messages and errors"
|
||||
name = "topic: reporting"
|
||||
|
||||
["topic: rewrite"]
|
||||
color = "0e8a16"
|
||||
description = "related to the assertion rewrite mechanism"
|
||||
name = "topic: rewrite"
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -24,6 +24,7 @@ src/_pytest/_version.py
|
||||
.eggs/
|
||||
|
||||
doc/*/_build
|
||||
doc/*/.doctrees
|
||||
build/
|
||||
dist/
|
||||
*.egg-info
|
||||
@@ -35,6 +36,11 @@ env/
|
||||
.cache
|
||||
.pytest_cache
|
||||
.coverage
|
||||
.coverage.*
|
||||
coverage.xml
|
||||
.ropeproject
|
||||
.idea
|
||||
.hypothesis
|
||||
.pydevproject
|
||||
.project
|
||||
.settings
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
exclude: doc/en/example/py2py3/test_py2.py
|
||||
repos:
|
||||
- repo: https://github.com/ambv/black
|
||||
rev: 18.4a4
|
||||
rev: 18.6b4
|
||||
hooks:
|
||||
- id: black
|
||||
args: [--safe, --quiet]
|
||||
language_version: python3.6
|
||||
language_version: python3
|
||||
- repo: https://github.com/asottile/blacken-docs
|
||||
rev: v0.1.1
|
||||
rev: v0.3.0
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
additional_dependencies: [black==18.5b1]
|
||||
language_version: python3.6
|
||||
additional_dependencies: [black==18.9b0]
|
||||
language_version: python3
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v1.2.3
|
||||
rev: v2.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: debug-statements
|
||||
exclude: _pytest/debugging.py
|
||||
language_version: python3
|
||||
- id: flake8
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.2.0
|
||||
language_version: python3
|
||||
- repo: https://github.com/asottile/reorder_python_imports
|
||||
rev: v1.3.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
- id: reorder-python-imports
|
||||
args: ['--application-directories=.:src']
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.8.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--keep-percent-format]
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.1.0
|
||||
hooks:
|
||||
- id: rst-backticks
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: rst
|
||||
@@ -33,4 +45,9 @@ repos:
|
||||
files: ^(CHANGELOG.rst|HOWTORELEASE.rst|README.rst|changelog/.*)$
|
||||
language: python
|
||||
additional_dependencies: [pygments, restructuredtext_lint]
|
||||
python_version: python3.6
|
||||
- id: changelogs-rst
|
||||
name: changelog filenames
|
||||
language: fail
|
||||
entry: 'changelog files must be named ####.(feature|bugfix|doc|deprecation|removal|vendor|trivial).rst'
|
||||
exclude: changelog/(\d+\.(feature|bugfix|doc|deprecation|removal|vendor|trivial).rst|README.rst|_template.rst)
|
||||
files: ^changelog/
|
||||
|
||||
102
.travis.yml
102
.travis.yml
@@ -1,50 +1,70 @@
|
||||
sudo: false
|
||||
language: python
|
||||
stages:
|
||||
- linting
|
||||
- test
|
||||
- deploy
|
||||
- baseline
|
||||
- name: test
|
||||
if: repo = pytest-dev/pytest AND tag IS NOT present
|
||||
- name: deploy
|
||||
if: repo = pytest-dev/pytest AND tag IS present
|
||||
python:
|
||||
- '3.6'
|
||||
install:
|
||||
- pip install --upgrade --pre tox
|
||||
env:
|
||||
matrix:
|
||||
# coveralls is not listed in tox's envlist, but should run in travis
|
||||
- TOXENV=coveralls
|
||||
# note: please use "tox --listenvs" to populate the build matrix below
|
||||
# please remove the linting env in all cases
|
||||
- TOXENV=py27
|
||||
- TOXENV=py34
|
||||
- TOXENV=py36
|
||||
- TOXENV=py27-pexpect
|
||||
- TOXENV=py27-xdist
|
||||
- TOXENV=py27-trial
|
||||
- TOXENV=py27-numpy
|
||||
- TOXENV=py27-pluggymaster
|
||||
- TOXENV=py36-pexpect
|
||||
- TOXENV=py36-xdist
|
||||
- TOXENV=py36-trial
|
||||
- TOXENV=py36-numpy
|
||||
- TOXENV=py36-pluggymaster
|
||||
# Specialized factors for py27.
|
||||
- TOXENV=py27-pexpect,py27-trial,py27-numpy
|
||||
- TOXENV=py27-nobyte
|
||||
- TOXENV=doctesting
|
||||
- TOXENV=docs
|
||||
- TOXENV=py27-xdist
|
||||
- TOXENV=py27-pluggymaster PYTEST_NO_COVERAGE=1
|
||||
# Specialized factors for py36.
|
||||
- TOXENV=py36-pexpect,py36-trial,py36-numpy
|
||||
- TOXENV=py36-xdist
|
||||
- TOXENV=py36-pluggymaster PYTEST_NO_COVERAGE=1
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- env: TOXENV=pypy
|
||||
# Coverage tracking is slow with pypy, skip it.
|
||||
- env: TOXENV=pypy PYTEST_NO_COVERAGE=1
|
||||
python: 'pypy-5.4'
|
||||
- env: TOXENV=py35
|
||||
python: '3.5'
|
||||
- env: TOXENV=py35-freeze
|
||||
python: '3.5'
|
||||
- env: TOXENV=py36-freeze PYTEST_NO_COVERAGE=1
|
||||
python: '3.6'
|
||||
- env: TOXENV=py37
|
||||
python: 'nightly'
|
||||
python: '3.7'
|
||||
sudo: required
|
||||
dist: xenial
|
||||
- &test-macos
|
||||
language: generic
|
||||
os: osx
|
||||
osx_image: xcode9.4
|
||||
sudo: required
|
||||
install:
|
||||
- python -m pip install --pre tox
|
||||
env: TOXENV=py27
|
||||
- <<: *test-macos
|
||||
env: TOXENV=py37
|
||||
before_install:
|
||||
- brew update
|
||||
# remove c++ include files because upgrading python as of 2018-10-23, also
|
||||
# attempts to upgrade gcc, and it fails because the include files already
|
||||
# exist. removing the include files is one of the solutions recommended by brew
|
||||
# this workaround might not be necessary in the future
|
||||
- rm '/usr/local/include/c++'
|
||||
- brew upgrade python
|
||||
- brew unlink python
|
||||
- brew link python
|
||||
|
||||
- stage: baseline
|
||||
env: TOXENV=py27
|
||||
- env: TOXENV=py34
|
||||
- env: TOXENV=py36
|
||||
- env: TOXENV=linting,docs,doctesting PYTEST_NO_COVERAGE=1
|
||||
|
||||
- stage: deploy
|
||||
python: '3.6'
|
||||
env:
|
||||
env: PYTEST_NO_COVERAGE=1
|
||||
install: pip install -U setuptools setuptools_scm
|
||||
script: skip
|
||||
deploy:
|
||||
@@ -57,17 +77,29 @@ jobs:
|
||||
on:
|
||||
tags: true
|
||||
repo: pytest-dev/pytest
|
||||
- stage: linting
|
||||
python: '3.6'
|
||||
env:
|
||||
install:
|
||||
- pip install pre-commit
|
||||
- pre-commit install-hooks
|
||||
script:
|
||||
- pre-commit run --all-files
|
||||
|
||||
before_script:
|
||||
- |
|
||||
if [[ "$PYTEST_NO_COVERAGE" != 1 ]]; then
|
||||
export COVERAGE_FILE="$PWD/.coverage"
|
||||
export COVERAGE_PROCESS_START="$PWD/.coveragerc"
|
||||
export _PYTEST_TOX_COVERAGE_RUN="coverage run -m"
|
||||
export _PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess
|
||||
fi
|
||||
|
||||
script: tox --recreate
|
||||
|
||||
after_success:
|
||||
- |
|
||||
if [[ "$PYTEST_NO_COVERAGE" != 1 ]]; then
|
||||
set -e
|
||||
pip install coverage
|
||||
coverage combine
|
||||
coverage xml --ignore-errors
|
||||
coverage report -m --ignore-errors
|
||||
bash <(curl -s https://codecov.io/bash) -Z -X gcov -X coveragepy -X search -X xcode -X gcovout -X fix -f coverage.xml -F "${TOXENV//-/,},linux"
|
||||
fi
|
||||
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
|
||||
24
AUTHORS
24
AUTHORS
@@ -10,9 +10,11 @@ Ahn Ki-Wook
|
||||
Alan Velasco
|
||||
Alexander Johnson
|
||||
Alexei Kozlenok
|
||||
Allan Feldman
|
||||
Anatoly Bubenkoff
|
||||
Anders Hovmöller
|
||||
Andras Tim
|
||||
Andrea Cimatoribus
|
||||
Andreas Zeidler
|
||||
Andrzej Ostrowski
|
||||
Andy Freeland
|
||||
@@ -46,7 +48,9 @@ Christian Boelsen
|
||||
Christian Theunert
|
||||
Christian Tismer
|
||||
Christopher Gilling
|
||||
CrazyMerlyn
|
||||
Cyrus Maden
|
||||
Dhiren Serai
|
||||
Daniel Grana
|
||||
Daniel Hahler
|
||||
Daniel Nuri
|
||||
@@ -71,6 +75,7 @@ Endre Galaczi
|
||||
Eric Hunsberger
|
||||
Eric Siegerman
|
||||
Erik M. Bray
|
||||
Fabio Zadrozny
|
||||
Feng Ma
|
||||
Florian Bruhin
|
||||
Floris Bruynooghe
|
||||
@@ -82,12 +87,15 @@ Greg Price
|
||||
Grig Gheorghiu
|
||||
Grigorii Eremeev (budulianin)
|
||||
Guido Wesdorp
|
||||
Guoqiang Zhang
|
||||
Harald Armin Massa
|
||||
Henk-Jaap Wagenaar
|
||||
Hugo van Kemenade
|
||||
Hui Wang (coldnight)
|
||||
Ian Bicking
|
||||
Ian Lesperance
|
||||
Ionuț Turturică
|
||||
Iwan Briquemont
|
||||
Jaap Broekhuizen
|
||||
Jan Balster
|
||||
Janne Vanhala
|
||||
@@ -96,6 +104,7 @@ Javier Domingo Cansino
|
||||
Javier Romero
|
||||
Jeff Rackauckas
|
||||
Jeff Widman
|
||||
Jenni Rinker
|
||||
John Eddie Ayson
|
||||
John Towler
|
||||
Jon Sonesen
|
||||
@@ -112,6 +121,7 @@ Katerina Koukiou
|
||||
Kevin Cox
|
||||
Kodi B. Arfer
|
||||
Kostis Anagnostopoulos
|
||||
Kyle Altendorf
|
||||
Lawrence Mitchell
|
||||
Lee Kamentsky
|
||||
Lev Maximov
|
||||
@@ -125,6 +135,7 @@ Maik Figura
|
||||
Mandeep Bhutani
|
||||
Manuel Krebber
|
||||
Marc Schlaich
|
||||
Marcelo Duarte Trevisani
|
||||
Marcin Bachry
|
||||
Mark Abramowitz
|
||||
Markus Unterwaditzer
|
||||
@@ -156,6 +167,7 @@ Oleg Sushchenko
|
||||
Oliver Bestwalter
|
||||
Omar Kohl
|
||||
Omer Hadari
|
||||
Ondřej Súkup
|
||||
Patrick Hayes
|
||||
Paweł Adamczak
|
||||
Pedro Algarvio
|
||||
@@ -170,6 +182,7 @@ Raphael Pierzina
|
||||
Raquel Alegre
|
||||
Ravi Chandra
|
||||
Roberto Polli
|
||||
Roland Puntaier
|
||||
Romain Dorgueil
|
||||
Roman Bolshakov
|
||||
Ronny Pfannschmidt
|
||||
@@ -178,7 +191,9 @@ Russel Winder
|
||||
Ryan Wooden
|
||||
Samuel Dion-Girardeau
|
||||
Samuele Pedroni
|
||||
Sankt Petersbug
|
||||
Segev Finer
|
||||
Serhii Mozghovyi
|
||||
Simon Gomizelj
|
||||
Skylar Downes
|
||||
Srinivas Reddy Thatiparthy
|
||||
@@ -187,6 +202,7 @@ Stefan Zimmermann
|
||||
Stefano Taschini
|
||||
Steffen Allner
|
||||
Stephan Obermann
|
||||
Tadek Teleżyński
|
||||
Tarcisio Fischer
|
||||
Tareq Alayan
|
||||
Ted Xiao
|
||||
@@ -195,18 +211,22 @@ Thomas Hisch
|
||||
Tim Strazny
|
||||
Tom Dalton
|
||||
Tom Viner
|
||||
Tomer Keren
|
||||
Trevor Bekolay
|
||||
Tyler Goodlet
|
||||
Tzu-ping Chung
|
||||
Vasily Kuznetsov
|
||||
Victor Maryama
|
||||
Victor Uriarte
|
||||
Vidar T. Fauske
|
||||
Virgil Dupras
|
||||
Vitaly Lashmanov
|
||||
Vlad Dragos
|
||||
Wil Cooley
|
||||
William Lee
|
||||
Wim Glenn
|
||||
Wouter van Ackooy
|
||||
Xuan Luong
|
||||
Xuecong Liao
|
||||
Zac Hatfield-Dodds
|
||||
Zoltán Máté
|
||||
Roland Puntaier
|
||||
Allan Feldman
|
||||
|
||||
796
CHANGELOG.rst
796
CHANGELOG.rst
@@ -1,3 +1,13 @@
|
||||
=================
|
||||
Changelog history
|
||||
=================
|
||||
|
||||
Versions follow `Semantic Versioning <https://semver.org/>`_ (``<major>.<minor>.<patch>``).
|
||||
|
||||
Backward incompatible (breaking) changes will only be introduced in major versions
|
||||
with advance notice in the **Deprecations** section of releases.
|
||||
|
||||
|
||||
..
|
||||
You should *NOT* be adding new change log entries to this file, this
|
||||
file is managed by towncrier. You *may* edit previous change logs to
|
||||
@@ -8,7 +18,727 @@
|
||||
|
||||
.. towncrier release notes start
|
||||
|
||||
Pytest 3.6.1 (2018-06-05)
|
||||
pytest 3.9.3 (2018-10-27)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#4174 <https://github.com/pytest-dev/pytest/issues/4174>`_: Fix "ValueError: Plugin already registered" with conftest plugins via symlink.
|
||||
|
||||
|
||||
- `#4181 <https://github.com/pytest-dev/pytest/issues/4181>`_: Handle race condition between creation and deletion of temporary folders.
|
||||
|
||||
|
||||
- `#4221 <https://github.com/pytest-dev/pytest/issues/4221>`_: Fix bug where the warning summary at the end of the test session was not showing the test where the warning was originated.
|
||||
|
||||
|
||||
- `#4243 <https://github.com/pytest-dev/pytest/issues/4243>`_: Fix regression when ``stacklevel`` for warnings was passed as positional argument on python2.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3851 <https://github.com/pytest-dev/pytest/issues/3851>`_: Add reference to ``empty_parameter_set_mark`` ini option in documentation of ``@pytest.mark.parametrize``
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#4028 <https://github.com/pytest-dev/pytest/issues/4028>`_: Revert patching of ``sys.breakpointhook`` since it appears to do nothing.
|
||||
|
||||
|
||||
- `#4233 <https://github.com/pytest-dev/pytest/issues/4233>`_: Apply an import sorter (``reorder-python-imports``) to the codebase.
|
||||
|
||||
|
||||
- `#4248 <https://github.com/pytest-dev/pytest/issues/4248>`_: Remove use of unnecessary compat shim, six.binary_type
|
||||
|
||||
|
||||
pytest 3.9.2 (2018-10-22)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#2909 <https://github.com/pytest-dev/pytest/issues/2909>`_: Improve error message when a recursive dependency between fixtures is detected.
|
||||
|
||||
|
||||
- `#3340 <https://github.com/pytest-dev/pytest/issues/3340>`_: Fix logging messages not shown in hooks ``pytest_sessionstart()`` and ``pytest_sessionfinish()``.
|
||||
|
||||
|
||||
- `#3533 <https://github.com/pytest-dev/pytest/issues/3533>`_: Fix unescaped XML raw objects in JUnit report for skipped tests
|
||||
|
||||
|
||||
- `#3691 <https://github.com/pytest-dev/pytest/issues/3691>`_: Python 2: safely format warning message about passing unicode strings to ``warnings.warn``, which may cause
|
||||
surprising ``MemoryError`` exception when monkey patching ``warnings.warn`` itself.
|
||||
|
||||
|
||||
- `#4026 <https://github.com/pytest-dev/pytest/issues/4026>`_: Improve error message when it is not possible to determine a function's signature.
|
||||
|
||||
|
||||
- `#4177 <https://github.com/pytest-dev/pytest/issues/4177>`_: Pin ``setuptools>=40.0`` to support ``py_modules`` in ``setup.cfg``
|
||||
|
||||
|
||||
- `#4179 <https://github.com/pytest-dev/pytest/issues/4179>`_: Restore the tmpdir behaviour of symlinking the current test run.
|
||||
|
||||
|
||||
- `#4192 <https://github.com/pytest-dev/pytest/issues/4192>`_: Fix filename reported by ``warnings.warn`` when using ``recwarn`` under python2.
|
||||
|
||||
|
||||
pytest 3.9.1 (2018-10-16)
|
||||
=========================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#4159 <https://github.com/pytest-dev/pytest/issues/4159>`_: For test-suites containing test classes, the information about the subclassed
|
||||
module is now output only if a higher verbosity level is specified (at least
|
||||
"-vv").
|
||||
|
||||
|
||||
pytest 3.9.0 (2018-10-15 - not published due to a release automation bug)
|
||||
=========================================================================
|
||||
|
||||
Deprecations
|
||||
------------
|
||||
|
||||
- `#3616 <https://github.com/pytest-dev/pytest/issues/3616>`_: The following accesses have been documented as deprecated for years, but are now actually emitting deprecation warnings.
|
||||
|
||||
* Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances. Now
|
||||
users will this warning::
|
||||
|
||||
usage of Function.Module is deprecated, please use pytest.Module instead
|
||||
|
||||
Users should just ``import pytest`` and access those objects using the ``pytest`` module.
|
||||
|
||||
* ``request.cached_setup``, this was the precursor of the setup/teardown mechanism available to fixtures. You can
|
||||
consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_.
|
||||
|
||||
* Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
|
||||
subclasses has been deprecated. Users instead should use ``pytest_collect_make_item`` to customize node types during
|
||||
collection.
|
||||
|
||||
This issue should affect only advanced plugins who create new collection types, so if you see this warning
|
||||
message please contact the authors so they can change the code.
|
||||
|
||||
* The warning that produces the message below has changed to ``RemovedInPytest4Warning``::
|
||||
|
||||
getfuncargvalue is deprecated, use getfixturevalue
|
||||
|
||||
|
||||
- `#3988 <https://github.com/pytest-dev/pytest/issues/3988>`_: Add a Deprecation warning for pytest.ensuretemp as it was deprecated since a while.
|
||||
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#2293 <https://github.com/pytest-dev/pytest/issues/2293>`_: Improve usage errors messages by hiding internal details which can be distracting and noisy.
|
||||
|
||||
This has the side effect that some error conditions that previously raised generic errors (such as
|
||||
``ValueError`` for unregistered marks) are now raising ``Failed`` exceptions.
|
||||
|
||||
|
||||
- `#3332 <https://github.com/pytest-dev/pytest/issues/3332>`_: Improve the error displayed when a ``conftest.py`` file could not be imported.
|
||||
|
||||
In order to implement this, a new ``chain`` parameter was added to ``ExceptionInfo.getrepr``
|
||||
to show or hide chained tracebacks in Python 3 (defaults to ``True``).
|
||||
|
||||
|
||||
- `#3849 <https://github.com/pytest-dev/pytest/issues/3849>`_: Add ``empty_parameter_set_mark=fail_at_collect`` ini option for raising an exception when parametrize collects an empty set.
|
||||
|
||||
|
||||
- `#3964 <https://github.com/pytest-dev/pytest/issues/3964>`_: Log messages generated in the collection phase are shown when
|
||||
live-logging is enabled and/or when they are logged to a file.
|
||||
|
||||
|
||||
- `#3985 <https://github.com/pytest-dev/pytest/issues/3985>`_: Introduce ``tmp_path`` as a fixture providing a Path object.
|
||||
|
||||
|
||||
- `#4013 <https://github.com/pytest-dev/pytest/issues/4013>`_: Deprecation warnings are now shown even if you customize the warnings filters yourself. In the previous version
|
||||
any customization would override pytest's filters and deprecation warnings would fall back to being hidden by default.
|
||||
|
||||
|
||||
- `#4073 <https://github.com/pytest-dev/pytest/issues/4073>`_: Allow specification of timeout for ``Testdir.runpytest_subprocess()`` and ``Testdir.run()``.
|
||||
|
||||
|
||||
- `#4098 <https://github.com/pytest-dev/pytest/issues/4098>`_: Add returncode argument to pytest.exit() to exit pytest with a specific return code.
|
||||
|
||||
|
||||
- `#4102 <https://github.com/pytest-dev/pytest/issues/4102>`_: Reimplement ``pytest.deprecated_call`` using ``pytest.warns`` so it supports the ``match='...'`` keyword argument.
|
||||
|
||||
This has the side effect that ``pytest.deprecated_call`` now raises ``pytest.fail.Exception`` instead
|
||||
of ``AssertionError``.
|
||||
|
||||
|
||||
- `#4149 <https://github.com/pytest-dev/pytest/issues/4149>`_: Require setuptools>=30.3 and move most of the metadata to ``setup.cfg``.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#2535 <https://github.com/pytest-dev/pytest/issues/2535>`_: Improve error message when test functions of ``unittest.TestCase`` subclasses use a parametrized fixture.
|
||||
|
||||
|
||||
- `#3057 <https://github.com/pytest-dev/pytest/issues/3057>`_: ``request.fixturenames`` now correctly returns the name of fixtures created by ``request.getfixturevalue()``.
|
||||
|
||||
|
||||
- `#3946 <https://github.com/pytest-dev/pytest/issues/3946>`_: Warning filters passed as command line options using ``-W`` now take precedence over filters defined in ``ini``
|
||||
configuration files.
|
||||
|
||||
|
||||
- `#4066 <https://github.com/pytest-dev/pytest/issues/4066>`_: Fix source reindenting by using ``textwrap.dedent`` directly.
|
||||
|
||||
|
||||
- `#4102 <https://github.com/pytest-dev/pytest/issues/4102>`_: ``pytest.warn`` will capture previously-warned warnings in Python 2. Previously they were never raised.
|
||||
|
||||
|
||||
- `#4108 <https://github.com/pytest-dev/pytest/issues/4108>`_: Resolve symbolic links for args.
|
||||
|
||||
This fixes running ``pytest tests/test_foo.py::test_bar``, where ``tests``
|
||||
is a symlink to ``project/app/tests``:
|
||||
previously ``project/app/conftest.py`` would be ignored for fixtures then.
|
||||
|
||||
|
||||
- `#4132 <https://github.com/pytest-dev/pytest/issues/4132>`_: Fix duplicate printing of internal errors when using ``--pdb``.
|
||||
|
||||
|
||||
- `#4135 <https://github.com/pytest-dev/pytest/issues/4135>`_: pathlib based tmpdir cleanup now correctly handles symlinks in the folder.
|
||||
|
||||
|
||||
- `#4152 <https://github.com/pytest-dev/pytest/issues/4152>`_: Display the filename when encountering ``SyntaxWarning``.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3713 <https://github.com/pytest-dev/pytest/issues/3713>`_: Update usefixtures documentation to clarify that it can't be used with fixture functions.
|
||||
|
||||
|
||||
- `#4058 <https://github.com/pytest-dev/pytest/issues/4058>`_: Update fixture documentation to specify that a fixture can be invoked twice in the scope it's defined for.
|
||||
|
||||
|
||||
- `#4064 <https://github.com/pytest-dev/pytest/issues/4064>`_: According to unittest.rst, setUpModule and tearDownModule were not implemented, but it turns out they are. So updated the documentation for unittest.
|
||||
|
||||
|
||||
- `#4151 <https://github.com/pytest-dev/pytest/issues/4151>`_: Add tempir testing example to CONTRIBUTING.rst guide
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#2293 <https://github.com/pytest-dev/pytest/issues/2293>`_: The internal ``MarkerError`` exception has been removed.
|
||||
|
||||
|
||||
- `#3988 <https://github.com/pytest-dev/pytest/issues/3988>`_: Port the implementation of tmpdir to pathlib.
|
||||
|
||||
|
||||
- `#4063 <https://github.com/pytest-dev/pytest/issues/4063>`_: Exclude 0.00 second entries from ``--duration`` output unless ``-vv`` is passed on the command-line.
|
||||
|
||||
|
||||
- `#4093 <https://github.com/pytest-dev/pytest/issues/4093>`_: Fixed formatting of string literals in internal tests.
|
||||
|
||||
|
||||
pytest 3.8.2 (2018-10-02)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- `#4036 <https://github.com/pytest-dev/pytest/issues/4036>`_: The ``item`` parameter of ``pytest_warning_captured`` hook is now documented as deprecated. We realized only after
|
||||
the ``3.8`` release that this parameter is incompatible with ``pytest-xdist``.
|
||||
|
||||
Our policy is to not deprecate features during bugfix releases, but in this case we believe it makes sense as we are
|
||||
only documenting it as deprecated, without issuing warnings which might potentially break test suites. This will get
|
||||
the word out that hook implementers should not use this parameter at all.
|
||||
|
||||
In a future release ``item`` will always be ``None`` and will emit a proper warning when a hook implementation
|
||||
makes use of it.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3539 <https://github.com/pytest-dev/pytest/issues/3539>`_: Fix reload on assertion rewritten modules.
|
||||
|
||||
|
||||
- `#4034 <https://github.com/pytest-dev/pytest/issues/4034>`_: The ``.user_properties`` attribute of ``TestReport`` objects is a list
|
||||
of (name, value) tuples, but could sometimes be instantiated as a tuple
|
||||
of tuples. It is now always a list.
|
||||
|
||||
|
||||
- `#4039 <https://github.com/pytest-dev/pytest/issues/4039>`_: No longer issue warnings about using ``pytest_plugins`` in non-top-level directories when using ``--pyargs``: the
|
||||
current ``--pyargs`` mechanism is not reliable and might give false negatives.
|
||||
|
||||
|
||||
- `#4040 <https://github.com/pytest-dev/pytest/issues/4040>`_: Exclude empty reports for passed tests when ``-rP`` option is used.
|
||||
|
||||
|
||||
- `#4051 <https://github.com/pytest-dev/pytest/issues/4051>`_: Improve error message when an invalid Python expression is passed to the ``-m`` option.
|
||||
|
||||
|
||||
- `#4056 <https://github.com/pytest-dev/pytest/issues/4056>`_: ``MonkeyPatch.setenv`` and ``MonkeyPatch.delenv`` issue a warning if the environment variable name is not ``str`` on Python 2.
|
||||
|
||||
In Python 2, adding ``unicode`` keys to ``os.environ`` causes problems with ``subprocess`` (and possible other modules),
|
||||
making this a subtle bug specially susceptible when used with ``from __future__ import unicode_literals``.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3928 <https://github.com/pytest-dev/pytest/issues/3928>`_: Add possible values for fixture scope to docs.
|
||||
|
||||
|
||||
pytest 3.8.1 (2018-09-22)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3286 <https://github.com/pytest-dev/pytest/issues/3286>`_: ``.pytest_cache`` directory is now automatically ignored by Git. Users who would like to contribute a solution for other SCMs please consult/comment on this issue.
|
||||
|
||||
|
||||
- `#3749 <https://github.com/pytest-dev/pytest/issues/3749>`_: Fix the following error during collection of tests inside packages::
|
||||
|
||||
TypeError: object of type 'Package' has no len()
|
||||
|
||||
|
||||
- `#3941 <https://github.com/pytest-dev/pytest/issues/3941>`_: Fix bug where indirect parametrization would consider the scope of all fixtures used by the test function to determine the parametrization scope, and not only the scope of the fixtures being parametrized.
|
||||
|
||||
|
||||
- `#3973 <https://github.com/pytest-dev/pytest/issues/3973>`_: Fix crash of the assertion rewriter if a test changed the current working directory without restoring it afterwards.
|
||||
|
||||
|
||||
- `#3998 <https://github.com/pytest-dev/pytest/issues/3998>`_: Fix issue that prevented some caplog properties (for example ``record_tuples``) from being available when entering the debugger with ``--pdb``.
|
||||
|
||||
|
||||
- `#3999 <https://github.com/pytest-dev/pytest/issues/3999>`_: Fix ``UnicodeDecodeError`` in python2.x when a class returns a non-ascii binary ``__repr__`` in an assertion which also contains non-ascii text.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3996 <https://github.com/pytest-dev/pytest/issues/3996>`_: New `Deprecations and Removals <https://docs.pytest.org/en/latest/deprecations.html>`_ page shows all currently
|
||||
deprecated features, the rationale to do so, and alternatives to update your code. It also list features removed
|
||||
from pytest in past major releases to help those with ancient pytest versions to upgrade.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#3955 <https://github.com/pytest-dev/pytest/issues/3955>`_: Improve pre-commit detection for changelog filenames
|
||||
|
||||
|
||||
- `#3975 <https://github.com/pytest-dev/pytest/issues/3975>`_: Remove legacy code around im_func as that was python2 only
|
||||
|
||||
|
||||
pytest 3.8.0 (2018-09-05)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- `#2452 <https://github.com/pytest-dev/pytest/issues/2452>`_: ``Config.warn`` and ``Node.warn`` have been
|
||||
deprecated, see `<https://docs.pytest.org/en/latest/deprecations.html#config-warn-and-node-warn>`_ for rationale and
|
||||
examples.
|
||||
|
||||
- `#3936 <https://github.com/pytest-dev/pytest/issues/3936>`_: ``@pytest.mark.filterwarnings`` second parameter is no longer regex-escaped,
|
||||
making it possible to actually use regular expressions to check the warning message.
|
||||
|
||||
**Note**: regex-escaping the match string was an implementation oversight that might break test suites which depend
|
||||
on the old behavior.
|
||||
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#2452 <https://github.com/pytest-dev/pytest/issues/2452>`_: Internal pytest warnings are now issued using the standard ``warnings`` module, making it possible to use
|
||||
the standard warnings filters to manage those warnings. This introduces ``PytestWarning``,
|
||||
``PytestDeprecationWarning`` and ``RemovedInPytest4Warning`` warning types as part of the public API.
|
||||
|
||||
Consult `the documentation <https://docs.pytest.org/en/latest/warnings.html#internal-pytest-warnings>`_ for more info.
|
||||
|
||||
|
||||
- `#2908 <https://github.com/pytest-dev/pytest/issues/2908>`_: ``DeprecationWarning`` and ``PendingDeprecationWarning`` are now shown by default if no other warning filter is
|
||||
configured. This makes pytest more compliant with
|
||||
`PEP-0506 <https://www.python.org/dev/peps/pep-0565/#recommended-filter-settings-for-test-runners>`_. See
|
||||
`the docs <https://docs.pytest.org/en/latest/warnings.html#deprecationwarning-and-pendingdeprecationwarning>`_ for
|
||||
more info.
|
||||
|
||||
|
||||
- `#3251 <https://github.com/pytest-dev/pytest/issues/3251>`_: Warnings are now captured and displayed during test collection.
|
||||
|
||||
|
||||
- `#3784 <https://github.com/pytest-dev/pytest/issues/3784>`_: ``PYTEST_DISABLE_PLUGIN_AUTOLOAD`` environment variable disables plugin auto-loading when set.
|
||||
|
||||
|
||||
- `#3829 <https://github.com/pytest-dev/pytest/issues/3829>`_: Added the ``count`` option to ``console_output_style`` to enable displaying the progress as a count instead of a percentage.
|
||||
|
||||
|
||||
- `#3837 <https://github.com/pytest-dev/pytest/issues/3837>`_: Added support for 'xfailed' and 'xpassed' outcomes to the ``pytester.RunResult.assert_outcomes`` signature.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3911 <https://github.com/pytest-dev/pytest/issues/3911>`_: Terminal writer now takes into account unicode character width when writing out progress.
|
||||
|
||||
|
||||
- `#3913 <https://github.com/pytest-dev/pytest/issues/3913>`_: Pytest now returns with correct exit code (EXIT_USAGEERROR, 4) when called with unknown arguments.
|
||||
|
||||
|
||||
- `#3918 <https://github.com/pytest-dev/pytest/issues/3918>`_: Improve performance of assertion rewriting.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3566 <https://github.com/pytest-dev/pytest/issues/3566>`_: Added a blurb in usage.rst for the usage of -r flag which is used to show an extra test summary info.
|
||||
|
||||
|
||||
- `#3907 <https://github.com/pytest-dev/pytest/issues/3907>`_: Corrected type of the exceptions collection passed to ``xfail``: ``raises`` argument accepts a ``tuple`` instead of ``list``.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#3853 <https://github.com/pytest-dev/pytest/issues/3853>`_: Removed ``"run all (no recorded failures)"`` message printed with ``--failed-first`` and ``--last-failed`` when there are no failed tests.
|
||||
|
||||
|
||||
pytest 3.7.4 (2018-08-29)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3506 <https://github.com/pytest-dev/pytest/issues/3506>`_: Fix possible infinite recursion when writing ``.pyc`` files.
|
||||
|
||||
|
||||
- `#3853 <https://github.com/pytest-dev/pytest/issues/3853>`_: Cache plugin now obeys the ``-q`` flag when ``--last-failed`` and ``--failed-first`` flags are used.
|
||||
|
||||
|
||||
- `#3883 <https://github.com/pytest-dev/pytest/issues/3883>`_: Fix bad console output when using ``console_output_style=classic``.
|
||||
|
||||
|
||||
- `#3888 <https://github.com/pytest-dev/pytest/issues/3888>`_: Fix macOS specific code using ``capturemanager`` plugin in doctests.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3902 <https://github.com/pytest-dev/pytest/issues/3902>`_: Fix pytest.org links
|
||||
|
||||
|
||||
pytest 3.7.3 (2018-08-26)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3033 <https://github.com/pytest-dev/pytest/issues/3033>`_: Fixtures during teardown can again use ``capsys`` and ``capfd`` to inspect output captured during tests.
|
||||
|
||||
|
||||
- `#3773 <https://github.com/pytest-dev/pytest/issues/3773>`_: Fix collection of tests from ``__init__.py`` files if they match the ``python_files`` configuration option.
|
||||
|
||||
|
||||
- `#3796 <https://github.com/pytest-dev/pytest/issues/3796>`_: Fix issue where teardown of fixtures of consecutive sub-packages were executed once, at the end of the outer
|
||||
package.
|
||||
|
||||
|
||||
- `#3816 <https://github.com/pytest-dev/pytest/issues/3816>`_: Fix bug where ``--show-capture=no`` option would still show logs printed during fixture teardown.
|
||||
|
||||
|
||||
- `#3819 <https://github.com/pytest-dev/pytest/issues/3819>`_: Fix ``stdout/stderr`` not getting captured when real-time cli logging is active.
|
||||
|
||||
|
||||
- `#3843 <https://github.com/pytest-dev/pytest/issues/3843>`_: Fix collection error when specifying test functions directly in the command line using ``test.py::test`` syntax together with ``--doctest-modules``.
|
||||
|
||||
|
||||
- `#3848 <https://github.com/pytest-dev/pytest/issues/3848>`_: Fix bugs where unicode arguments could not be passed to ``testdir.runpytest`` on Python 2.
|
||||
|
||||
|
||||
- `#3854 <https://github.com/pytest-dev/pytest/issues/3854>`_: Fix double collection of tests within packages when the filename starts with a capital letter.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3824 <https://github.com/pytest-dev/pytest/issues/3824>`_: Added example for multiple glob pattern matches in ``python_files``.
|
||||
|
||||
|
||||
- `#3833 <https://github.com/pytest-dev/pytest/issues/3833>`_: Added missing docs for ``pytester.Testdir``.
|
||||
|
||||
|
||||
- `#3870 <https://github.com/pytest-dev/pytest/issues/3870>`_: Correct documentation for setuptools integration.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#3826 <https://github.com/pytest-dev/pytest/issues/3826>`_: Replace broken type annotations with type comments.
|
||||
|
||||
|
||||
- `#3845 <https://github.com/pytest-dev/pytest/issues/3845>`_: Remove a reference to issue `#568 <https://github.com/pytest-dev/pytest/issues/568>`_ from the documentation, which has since been
|
||||
fixed.
|
||||
|
||||
|
||||
pytest 3.7.2 (2018-08-16)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3671 <https://github.com/pytest-dev/pytest/issues/3671>`_: Fix ``filterwarnings`` not being registered as a builtin mark.
|
||||
|
||||
|
||||
- `#3768 <https://github.com/pytest-dev/pytest/issues/3768>`_, `#3789 <https://github.com/pytest-dev/pytest/issues/3789>`_: Fix test collection from packages mixed with normal directories.
|
||||
|
||||
|
||||
- `#3771 <https://github.com/pytest-dev/pytest/issues/3771>`_: Fix infinite recursion during collection if a ``pytest_ignore_collect`` hook returns ``False`` instead of ``None``.
|
||||
|
||||
|
||||
- `#3774 <https://github.com/pytest-dev/pytest/issues/3774>`_: Fix bug where decorated fixtures would lose functionality (for example ``@mock.patch``).
|
||||
|
||||
|
||||
- `#3775 <https://github.com/pytest-dev/pytest/issues/3775>`_: Fix bug where importing modules or other objects with prefix ``pytest_`` prefix would raise a ``PluginValidationError``.
|
||||
|
||||
|
||||
- `#3788 <https://github.com/pytest-dev/pytest/issues/3788>`_: Fix ``AttributeError`` during teardown of ``TestCase`` subclasses which raise an exception during ``__init__``.
|
||||
|
||||
|
||||
- `#3804 <https://github.com/pytest-dev/pytest/issues/3804>`_: Fix traceback reporting for exceptions with ``__cause__`` cycles.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3746 <https://github.com/pytest-dev/pytest/issues/3746>`_: Add documentation for ``metafunc.config`` that had been mistakenly hidden.
|
||||
|
||||
|
||||
pytest 3.7.1 (2018-08-02)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#3473 <https://github.com/pytest-dev/pytest/issues/3473>`_: Raise immediately if ``approx()`` is given an expected value of a type it doesn't understand (e.g. strings, nested dicts, etc.).
|
||||
|
||||
|
||||
- `#3712 <https://github.com/pytest-dev/pytest/issues/3712>`_: Correctly represent the dimensions of an numpy array when calling ``repr()`` on ``approx()``.
|
||||
|
||||
- `#3742 <https://github.com/pytest-dev/pytest/issues/3742>`_: Fix incompatibility with third party plugins during collection, which produced the error ``object has no attribute '_collectfile'``.
|
||||
|
||||
- `#3745 <https://github.com/pytest-dev/pytest/issues/3745>`_: Display the absolute path if ``cache_dir`` is not relative to the ``rootdir`` instead of failing.
|
||||
|
||||
|
||||
- `#3747 <https://github.com/pytest-dev/pytest/issues/3747>`_: Fix compatibility problem with plugins and the warning code issued by fixture functions when they are called directly.
|
||||
|
||||
|
||||
- `#3748 <https://github.com/pytest-dev/pytest/issues/3748>`_: Fix infinite recursion in ``pytest.approx`` with arrays in ``numpy<1.13``.
|
||||
|
||||
|
||||
- `#3757 <https://github.com/pytest-dev/pytest/issues/3757>`_: Pin pathlib2 to ``>=2.2.0`` as we require ``__fspath__`` support.
|
||||
|
||||
|
||||
- `#3763 <https://github.com/pytest-dev/pytest/issues/3763>`_: Fix ``TypeError`` when the assertion message is ``bytes`` in python 3.
|
||||
|
||||
|
||||
pytest 3.7.0 (2018-07-30)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- `#2639 <https://github.com/pytest-dev/pytest/issues/2639>`_: ``pytest_namespace`` has been `deprecated <https://docs.pytest.org/en/latest/deprecations.html#pytest-namespace>`_.
|
||||
|
||||
|
||||
- `#3661 <https://github.com/pytest-dev/pytest/issues/3661>`_: Calling a fixture function directly, as opposed to request them in a test function, now issues a ``RemovedInPytest4Warning``. See `the documentation for rationale and examples <https://docs.pytest.org/en/latest/deprecations.html#calling-fixtures-directly>`_.
|
||||
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- `#2283 <https://github.com/pytest-dev/pytest/issues/2283>`_: New ``package`` fixture scope: fixtures are finalized when the last test of a *package* finishes. This feature is considered **experimental**, so use it sparingly.
|
||||
|
||||
|
||||
- `#3576 <https://github.com/pytest-dev/pytest/issues/3576>`_: ``Node.add_marker`` now supports an ``append=True/False`` parameter to determine whether the mark comes last (default) or first.
|
||||
|
||||
|
||||
- `#3579 <https://github.com/pytest-dev/pytest/issues/3579>`_: Fixture ``caplog`` now has a ``messages`` property, providing convenient access to the format-interpolated log messages without the extra data provided by the formatter/handler.
|
||||
|
||||
|
||||
- `#3610 <https://github.com/pytest-dev/pytest/issues/3610>`_: New ``--trace`` option to enter the debugger at the start of a test.
|
||||
|
||||
|
||||
- `#3623 <https://github.com/pytest-dev/pytest/issues/3623>`_: Introduce ``pytester.copy_example`` as helper to do acceptance tests against examples from the project.
|
||||
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- `#2220 <https://github.com/pytest-dev/pytest/issues/2220>`_: Fix a bug where fixtures overridden by direct parameters (for example parametrization) were being instantiated even if they were not being used by a test.
|
||||
|
||||
|
||||
- `#3695 <https://github.com/pytest-dev/pytest/issues/3695>`_: Fix ``ApproxNumpy`` initialisation argument mixup, ``abs`` and ``rel`` tolerances were flipped causing strange comparsion results.
|
||||
Add tests to check ``abs`` and ``rel`` tolerances for ``np.array`` and test for expecting ``nan`` with ``np.array()``
|
||||
|
||||
|
||||
- `#980 <https://github.com/pytest-dev/pytest/issues/980>`_: Fix truncated locals output in verbose mode.
|
||||
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- `#3295 <https://github.com/pytest-dev/pytest/issues/3295>`_: Correct the usage documentation of ``--last-failed-no-failures`` by adding the missing ``--last-failed`` argument in the presented examples, because they are misleading and lead to think that the missing argument is not needed.
|
||||
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- `#3519 <https://github.com/pytest-dev/pytest/issues/3519>`_: Now a ``README.md`` file is created in ``.pytest_cache`` to make it clear why the directory exists.
|
||||
|
||||
|
||||
pytest 3.6.4 (2018-07-28)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Invoke pytest using ``-mpytest`` so ``sys.path`` does not get polluted by packages installed in ``site-packages``. (`#742 <https://github.com/pytest-dev/pytest/issues/742>`_)
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Use ``smtp_connection`` instead of ``smtp`` in fixtures documentation to avoid possible confusion. (`#3592 <https://github.com/pytest-dev/pytest/issues/3592>`_)
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- Remove obsolete ``__future__`` imports. (`#2319 <https://github.com/pytest-dev/pytest/issues/2319>`_)
|
||||
|
||||
- Add CITATION to provide information on how to formally cite pytest. (`#3402 <https://github.com/pytest-dev/pytest/issues/3402>`_)
|
||||
|
||||
- Replace broken type annotations with type comments. (`#3635 <https://github.com/pytest-dev/pytest/issues/3635>`_)
|
||||
|
||||
- Pin ``pluggy`` to ``<0.8``. (`#3727 <https://github.com/pytest-dev/pytest/issues/3727>`_)
|
||||
|
||||
|
||||
pytest 3.6.3 (2018-07-04)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix ``ImportWarning`` triggered by explicit relative imports in
|
||||
assertion-rewritten package modules. (`#3061
|
||||
<https://github.com/pytest-dev/pytest/issues/3061>`_)
|
||||
|
||||
- Fix error in ``pytest.approx`` when dealing with 0-dimension numpy
|
||||
arrays. (`#3593 <https://github.com/pytest-dev/pytest/issues/3593>`_)
|
||||
|
||||
- No longer raise ``ValueError`` when using the ``get_marker`` API. (`#3605
|
||||
<https://github.com/pytest-dev/pytest/issues/3605>`_)
|
||||
|
||||
- Fix problem where log messages with non-ascii characters would not
|
||||
appear in the output log file.
|
||||
(`#3630 <https://github.com/pytest-dev/pytest/issues/3630>`_)
|
||||
|
||||
- No longer raise ``AttributeError`` when legacy marks can't be stored in
|
||||
functions. (`#3631 <https://github.com/pytest-dev/pytest/issues/3631>`_)
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- The description above the example for ``@pytest.mark.skipif`` now better
|
||||
matches the code. (`#3611
|
||||
<https://github.com/pytest-dev/pytest/issues/3611>`_)
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- Internal refactoring: removed unused ``CallSpec2tox ._globalid_args``
|
||||
attribute and ``metafunc`` parameter from ``CallSpec2.copy()``. (`#3598
|
||||
<https://github.com/pytest-dev/pytest/issues/3598>`_)
|
||||
|
||||
- Silence usage of ``reduce`` warning in Python 2 (`#3609
|
||||
<https://github.com/pytest-dev/pytest/issues/3609>`_)
|
||||
|
||||
- Fix usage of ``attr.ib`` deprecated ``convert`` parameter. (`#3653
|
||||
<https://github.com/pytest-dev/pytest/issues/3653>`_)
|
||||
|
||||
|
||||
pytest 3.6.2 (2018-06-20)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix regression in ``Node.add_marker`` by extracting the mark object of a
|
||||
``MarkDecorator``. (`#3555
|
||||
<https://github.com/pytest-dev/pytest/issues/3555>`_)
|
||||
|
||||
- Warnings without ``location`` were reported as ``None``. This is corrected to
|
||||
now report ``<undetermined location>``. (`#3563
|
||||
<https://github.com/pytest-dev/pytest/issues/3563>`_)
|
||||
|
||||
- Continue to call finalizers in the stack when a finalizer in a former scope
|
||||
raises an exception. (`#3569
|
||||
<https://github.com/pytest-dev/pytest/issues/3569>`_)
|
||||
|
||||
- Fix encoding error with ``print`` statements in doctests (`#3583
|
||||
<https://github.com/pytest-dev/pytest/issues/3583>`_)
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Add documentation for the ``--strict`` flag. (`#3549
|
||||
<https://github.com/pytest-dev/pytest/issues/3549>`_)
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
------------------------
|
||||
|
||||
- Update old quotation style to parens in fixture.rst documentation. (`#3525
|
||||
<https://github.com/pytest-dev/pytest/issues/3525>`_)
|
||||
|
||||
- Improve display of hint about ``--fulltrace`` with ``KeyboardInterrupt``.
|
||||
(`#3545 <https://github.com/pytest-dev/pytest/issues/3545>`_)
|
||||
|
||||
- pytest's testsuite is no longer runnable through ``python setup.py test`` --
|
||||
instead invoke ``pytest`` or ``tox`` directly. (`#3552
|
||||
<https://github.com/pytest-dev/pytest/issues/3552>`_)
|
||||
|
||||
- Fix typo in documentation (`#3567
|
||||
<https://github.com/pytest-dev/pytest/issues/3567>`_)
|
||||
|
||||
|
||||
pytest 3.6.1 (2018-06-05)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -48,11 +778,11 @@ Trivial/Internal Changes
|
||||
- Fix if in tests to support 3.7.0b5, where a docstring handling in AST got
|
||||
reverted. (`#3530 <https://github.com/pytest-dev/pytest/issues/3530>`_)
|
||||
|
||||
- Remove some python2.5 compatibility code. (`#3629
|
||||
<https://github.com/pytest-dev/pytest/issues/3629>`_)
|
||||
- Remove some python2.5 compatibility code. (`#3529
|
||||
<https://github.com/pytest-dev/pytest/issues/3529>`_)
|
||||
|
||||
|
||||
Pytest 3.6.0 (2018-05-23)
|
||||
pytest 3.6.0 (2018-05-23)
|
||||
=========================
|
||||
|
||||
Features
|
||||
@@ -138,7 +868,7 @@ Trivial/Internal Changes
|
||||
3.7 or newer. (`#3497 <https://github.com/pytest-dev/pytest/issues/3497>`_)
|
||||
|
||||
|
||||
Pytest 3.5.1 (2018-04-23)
|
||||
pytest 3.5.1 (2018-04-23)
|
||||
=========================
|
||||
|
||||
|
||||
@@ -190,7 +920,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/3398>`_)
|
||||
|
||||
|
||||
Pytest 3.5.0 (2018-03-21)
|
||||
pytest 3.5.0 (2018-03-21)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
@@ -201,7 +931,7 @@ Deprecations and Removals
|
||||
<https://github.com/pytest-dev/pytest/issues/2770>`_)
|
||||
|
||||
- Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
|
||||
files, because they "leak" to the entire directory tree. (`#3084
|
||||
files, because they "leak" to the entire directory tree. `See the docs <https://docs.pytest.org/en/latest/deprecations.html#pytest-plugins-in-non-top-level-conftest-files>`_ for the rationale behind this decision (`#3084
|
||||
<https://github.com/pytest-dev/pytest/issues/3084>`_)
|
||||
|
||||
|
||||
@@ -253,7 +983,7 @@ Features
|
||||
``pytest_runtest_logfinish`` hooks when live logs are enabled. (`#3189
|
||||
<https://github.com/pytest-dev/pytest/issues/3189>`_)
|
||||
|
||||
- Passing `--log-cli-level` in the command-line now automatically activates
|
||||
- Passing ``--log-cli-level`` in the command-line now automatically activates
|
||||
live logging. (`#3190 <https://github.com/pytest-dev/pytest/issues/3190>`_)
|
||||
|
||||
- Add command line option ``--deselect`` to allow deselection of individual
|
||||
@@ -342,7 +1072,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/3308>`_)
|
||||
|
||||
|
||||
Pytest 3.4.2 (2018-03-04)
|
||||
pytest 3.4.2 (2018-03-04)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -379,7 +1109,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/3259>`_)
|
||||
|
||||
|
||||
Pytest 3.4.1 (2018-02-20)
|
||||
pytest 3.4.1 (2018-02-20)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -440,7 +1170,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/985>`_)
|
||||
|
||||
|
||||
Pytest 3.4.0 (2018-01-30)
|
||||
pytest 3.4.0 (2018-01-30)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
@@ -572,7 +1302,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/3129>`_)
|
||||
|
||||
|
||||
Pytest 3.3.2 (2017-12-25)
|
||||
pytest 3.3.2 (2017-12-25)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -605,11 +1335,11 @@ Trivial/Internal Changes
|
||||
- Code cleanup. (`#3015 <https://github.com/pytest-dev/pytest/issues/3015>`_,
|
||||
`#3021 <https://github.com/pytest-dev/pytest/issues/3021>`_)
|
||||
|
||||
- Clean up code by replacing imports and references of `_ast` to `ast`. (`#3018
|
||||
<https://github.com/pytest-dev/pytest/issues/3018>`_)
|
||||
- Clean up code by replacing imports and references of ``_ast`` to ``ast``.
|
||||
(`#3018 <https://github.com/pytest-dev/pytest/issues/3018>`_)
|
||||
|
||||
|
||||
Pytest 3.3.1 (2017-12-05)
|
||||
pytest 3.3.1 (2017-12-05)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -651,13 +1381,13 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/2949>`_)
|
||||
|
||||
|
||||
Pytest 3.3.0 (2017-11-23)
|
||||
pytest 3.3.0 (2017-11-23)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Pytest no longer supports Python **2.6** and **3.3**. Those Python versions
|
||||
- pytest no longer supports Python **2.6** and **3.3**. Those Python versions
|
||||
are EOL for some time now and incur maintenance and compatibility costs on
|
||||
the pytest core team, and following up with the rest of the community we
|
||||
decided that they will no longer be supported starting on this version. Users
|
||||
@@ -711,7 +1441,7 @@ Features
|
||||
- Match ``warns`` signature to ``raises`` by adding ``match`` keyword. (`#2708
|
||||
<https://github.com/pytest-dev/pytest/issues/2708>`_)
|
||||
|
||||
- Pytest now captures and displays output from the standard ``logging`` module.
|
||||
- pytest now captures and displays output from the standard ``logging`` module.
|
||||
The user can control the logging level to be captured by specifying options
|
||||
in ``pytest.ini``, the command line and also during individual tests using
|
||||
markers. Also, a ``caplog`` fixture is available that enables users to test
|
||||
@@ -776,7 +1506,7 @@ Bug Fixes
|
||||
avoids a number of potential problems. (`#2751
|
||||
<https://github.com/pytest-dev/pytest/issues/2751>`_)
|
||||
|
||||
- Pytest no longer complains about warnings with unicode messages being
|
||||
- pytest no longer complains about warnings with unicode messages being
|
||||
non-ascii compatible even for ascii-compatible messages. As a result of this,
|
||||
warnings with unicode messages are converted first to an ascii representation
|
||||
for safety. (`#2809 <https://github.com/pytest-dev/pytest/issues/2809>`_)
|
||||
@@ -828,7 +1558,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/2922>`_)
|
||||
|
||||
|
||||
Pytest 3.2.5 (2017-11-15)
|
||||
pytest 3.2.5 (2017-11-15)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -839,7 +1569,7 @@ Bug Fixes
|
||||
<https://github.com/pytest-dev/pytest/issues/2926>`_)
|
||||
|
||||
|
||||
Pytest 3.2.4 (2017-11-13)
|
||||
pytest 3.2.4 (2017-11-13)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -888,7 +1618,7 @@ Improved Documentation
|
||||
<https://github.com/pytest-dev/pytest/issues/911>`_)
|
||||
|
||||
|
||||
Pytest 3.2.3 (2017-10-03)
|
||||
pytest 3.2.3 (2017-10-03)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -928,13 +1658,13 @@ Trivial/Internal Changes
|
||||
(`#2765 <https://github.com/pytest-dev/pytest/issues/2765>`_)
|
||||
|
||||
|
||||
Pytest 3.2.2 (2017-09-06)
|
||||
pytest 3.2.2 (2017-09-06)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Calling the deprecated `request.getfuncargvalue()` now shows the source of
|
||||
- Calling the deprecated ``request.getfuncargvalue()`` now shows the source of
|
||||
the call. (`#2681 <https://github.com/pytest-dev/pytest/issues/2681>`_)
|
||||
|
||||
- Allow tests declared as ``@staticmethod`` to use fixtures. (`#2699
|
||||
@@ -956,10 +1686,10 @@ Improved Documentation
|
||||
``pytest.mark.MARKER_NAME.__call__`` (`#2604
|
||||
<https://github.com/pytest-dev/pytest/issues/2604>`_)
|
||||
|
||||
- In one of the simple examples, use `pytest_collection_modifyitems()` to skip
|
||||
- In one of the simple examples, use ``pytest_collection_modifyitems()`` to skip
|
||||
tests based on a command-line option, allowing its sharing while preventing a
|
||||
user error when acessing `pytest.config` before the argument parsing. (`#2653
|
||||
<https://github.com/pytest-dev/pytest/issues/2653>`_)
|
||||
user error when acessing ``pytest.config`` before the argument parsing.
|
||||
(`#2653 <https://github.com/pytest-dev/pytest/issues/2653>`_)
|
||||
|
||||
|
||||
Trivial/Internal Changes
|
||||
@@ -975,7 +1705,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/2739>`_)
|
||||
|
||||
|
||||
Pytest 3.2.1 (2017-08-08)
|
||||
pytest 3.2.1 (2017-08-08)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -1005,7 +1735,7 @@ Improved Documentation
|
||||
<https://github.com/pytest-dev/pytest/issues/2626>`_)
|
||||
|
||||
|
||||
Pytest 3.2.0 (2017-07-30)
|
||||
pytest 3.2.0 (2017-07-30)
|
||||
=========================
|
||||
|
||||
Deprecations and Removals
|
||||
@@ -1037,7 +1767,7 @@ Features
|
||||
from parent classes or modules. (`#2516 <https://github.com/pytest-
|
||||
dev/pytest/issues/2516>`_)
|
||||
|
||||
- Collection ignores local virtualenvs by default; `--collect-in-virtualenv`
|
||||
- Collection ignores local virtualenvs by default; ``--collect-in-virtualenv``
|
||||
overrides this behavior. (`#2518 <https://github.com/pytest-
|
||||
dev/pytest/issues/2518>`_)
|
||||
|
||||
@@ -1171,7 +1901,7 @@ Trivial/Internal Changes
|
||||
<https://github.com/pytest-dev/pytest/issues/2620>`_)
|
||||
|
||||
|
||||
Pytest 3.1.3 (2017-07-03)
|
||||
pytest 3.1.3 (2017-07-03)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -1217,7 +1947,7 @@ Trivial/Internal Changes
|
||||
(`#2499 <https://github.com/pytest-dev/pytest/issues/2499>`_)
|
||||
|
||||
|
||||
Pytest 3.1.2 (2017-06-08)
|
||||
pytest 3.1.2 (2017-06-08)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
@@ -1249,7 +1979,7 @@ Improved Documentation
|
||||
and improve overall flow of the ``skipping`` docs. (#810)
|
||||
|
||||
|
||||
Pytest 3.1.1 (2017-05-30)
|
||||
pytest 3.1.1 (2017-05-30)
|
||||
=========================
|
||||
|
||||
Bug Fixes
|
||||
|
||||
16
CITATION
Normal file
16
CITATION
Normal file
@@ -0,0 +1,16 @@
|
||||
NOTE: Change "x.y" by the version you use. If you are unsure about which version
|
||||
you are using run: `pip show pytest`.
|
||||
|
||||
Text:
|
||||
|
||||
[pytest] pytest x.y, 2004
|
||||
Krekel et al., https://github.com/pytest-dev/pytest
|
||||
|
||||
BibTeX:
|
||||
|
||||
@misc{pytestx.y,
|
||||
title = {pytest x.y},
|
||||
author = {Krekel, Holger and Oliveira, Bruno and Pfannschmidt, Ronny and Bruynooghe, Floris and Laugher, Brianna and Bruhin, Florian},
|
||||
year = {2004},
|
||||
url = {https://github.com/pytest-dev/pytest},
|
||||
}
|
||||
@@ -162,11 +162,11 @@ Preparing Pull Requests
|
||||
Short version
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
#. Fork the repository;
|
||||
#. enable and install pre-commit https://pre-commit.com/ to ensure styleguides and codechecks are followed
|
||||
#. Target ``master`` for bugfixes and doc changes;
|
||||
#. Fork the repository.
|
||||
#. Enable and install `pre-commit <https://pre-commit.com>`_ to ensure style-guides and code checks are followed.
|
||||
#. Target ``master`` for bugfixes and doc changes.
|
||||
#. Target ``features`` for new features or functionality changes.
|
||||
#. Follow **PEP-8**. There's a ``tox`` command to help fixing it: ``tox -e fix-lint``.
|
||||
#. Follow **PEP-8** for naming and `black <https://github.com/ambv/black>`_ for formatting.
|
||||
#. Tests are run using ``tox``::
|
||||
|
||||
tox -e linting,py27,py36
|
||||
@@ -177,7 +177,7 @@ Short version
|
||||
and one of ``bugfix``, ``removal``, ``feature``, ``vendor``, ``doc`` or
|
||||
``trivial`` for the issue type.
|
||||
#. Unless your change is a trivial or a documentation fix (e.g., a typo or reword of a small section) please
|
||||
add yourself to the ``AUTHORS`` file, in alphabetical order;
|
||||
add yourself to the ``AUTHORS`` file, in alphabetical order.
|
||||
|
||||
|
||||
Long version
|
||||
@@ -217,15 +217,15 @@ Here is a simple overview, with pytest-specific bits:
|
||||
If you need some help with Git, follow this quick start
|
||||
guide: https://git.wiki.kernel.org/index.php/QuickStart
|
||||
|
||||
#. install pre-commit and install its hook on the pytest repo
|
||||
#. Install `pre-commit <https://pre-commit.com>`_ and its hook on the pytest repo::
|
||||
|
||||
https://pre-commit.com/ is a framework for managing and maintaining multi-language pre-commit hooks
|
||||
pytest uses pre-commit to ensure code-style and code formatting is the same
|
||||
$ pip install --user pre-commit
|
||||
$ pre-commit install
|
||||
|
||||
$ pip install --user pre-commit
|
||||
$ pre-commit install
|
||||
Afterwards ``pre-commit`` will run whenever you commit.
|
||||
|
||||
Afterwards pre-commit will run whenever you commit.
|
||||
https://pre-commit.com/ is a framework for managing and maintaining multi-language pre-commit hooks
|
||||
to ensure code-style and code formatting is consistent.
|
||||
|
||||
#. Install tox
|
||||
|
||||
@@ -245,15 +245,7 @@ Here is a simple overview, with pytest-specific bits:
|
||||
This command will run tests via the "tox" tool against Python 2.7 and 3.6
|
||||
and also perform "lint" coding-style checks.
|
||||
|
||||
#. You can now edit your local working copy. Please follow PEP-8.
|
||||
|
||||
You can now make the changes you want and run the tests again as necessary.
|
||||
|
||||
If you have too much linting errors, try running::
|
||||
|
||||
$ tox -e fix-lint
|
||||
|
||||
To fix pep8 related errors.
|
||||
#. You can now edit your local working copy and run the tests again as necessary. Please follow PEP-8 for naming.
|
||||
|
||||
You can pass different options to ``tox``. For example, to run tests on Python 2.7 and pass options to pytest
|
||||
(e.g. enter pdb on failure) to pytest you can do::
|
||||
@@ -264,6 +256,9 @@ Here is a simple overview, with pytest-specific bits:
|
||||
|
||||
$ tox -e py36 -- testing/test_config.py
|
||||
|
||||
|
||||
When committing, ``pre-commit`` will re-format the files if necessary.
|
||||
|
||||
#. Commit and push once your tests pass and you are happy with your change(s)::
|
||||
|
||||
$ git commit -a -m "<commit message>"
|
||||
@@ -285,6 +280,47 @@ Here is a simple overview, with pytest-specific bits:
|
||||
base: features # if it's a feature
|
||||
|
||||
|
||||
Writing Tests
|
||||
----------------------------
|
||||
|
||||
Writing tests for plugins or for pytest itself is often done using the `testdir fixture <https://docs.pytest.org/en/latest/reference.html#testdir>`_, as a "black-box" test.
|
||||
|
||||
For example, to ensure a simple test passes you can write:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_true_assertion(testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
def test_foo():
|
||||
assert True
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result.assert_outcomes(failed=0, passed=1)
|
||||
|
||||
|
||||
Alternatively, it is possible to make checks based on the actual output of the termal using
|
||||
*glob-like* expressions:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_true_assertion(testdir):
|
||||
testdir.makepyfile(
|
||||
"""
|
||||
def test_foo():
|
||||
assert False
|
||||
"""
|
||||
)
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(["*assert False*", "*1 failed*"])
|
||||
|
||||
When choosing a file where to write a new test, take a look at the existing files and see if there's
|
||||
one file which looks like a good fit. For example, a regression test about a bug in the ``--lf`` option
|
||||
should go into ``test_cacheprovider.py``, given that this option is implemented in ``cacheprovider.py``.
|
||||
If in doubt, go ahead and open a PR with your best guess and we can discuss this over the code.
|
||||
|
||||
|
||||
Joining the Development Team
|
||||
----------------------------
|
||||
|
||||
|
||||
@@ -10,10 +10,6 @@ taking a lot of time to make a new one.
|
||||
pytest releases must be prepared on **Linux** because the docs and examples expect
|
||||
to be executed in that platform.
|
||||
|
||||
#. Install development dependencies in a virtual environment with::
|
||||
|
||||
pip3 install -U -r tasks/requirements.txt
|
||||
|
||||
#. Create a branch ``release-X.Y.Z`` with the version for the release.
|
||||
|
||||
* **patch releases**: from the latest ``master``;
|
||||
@@ -22,18 +18,23 @@ taking a lot of time to make a new one.
|
||||
|
||||
Ensure your are in a clean work tree.
|
||||
|
||||
#. Generate docs, changelog, announcements and a **local** tag::
|
||||
#. Using ``tox``, generate docs, changelog, announcements::
|
||||
|
||||
invoke generate.pre-release <VERSION>
|
||||
$ tox -e release -- <VERSION>
|
||||
|
||||
This will generate a commit with all the changes ready for pushing.
|
||||
|
||||
#. Open a PR for this branch targeting ``master``.
|
||||
|
||||
#. After all tests pass and the PR has been approved, publish to PyPI by pushing the tag::
|
||||
|
||||
git tag <VERSION>
|
||||
git push git@github.com:pytest-dev/pytest.git <VERSION>
|
||||
|
||||
Wait for the deploy to complete, then make sure it is `available on PyPI <https://pypi.org/project/pytest>`_.
|
||||
|
||||
#. Merge the PR into ``master``.
|
||||
|
||||
#. Send an email announcement with the contents from::
|
||||
|
||||
doc/en/announce/release-<VERSION>.rst
|
||||
|
||||
30
README.rst
30
README.rst
@@ -1,8 +1,9 @@
|
||||
.. image:: http://docs.pytest.org/en/latest/_static/pytest1.png
|
||||
:target: http://docs.pytest.org
|
||||
.. image:: https://docs.pytest.org/en/latest/_static/pytest1.png
|
||||
:target: https://docs.pytest.org/en/latest/
|
||||
:align: center
|
||||
:alt: pytest
|
||||
|
||||
|
||||
------
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/pytest.svg
|
||||
@@ -14,8 +15,9 @@
|
||||
.. image:: https://img.shields.io/pypi/pyversions/pytest.svg
|
||||
:target: https://pypi.org/project/pytest/
|
||||
|
||||
.. image:: https://img.shields.io/coveralls/pytest-dev/pytest/master.svg
|
||||
:target: https://coveralls.io/r/pytest-dev/pytest
|
||||
.. image:: https://codecov.io/gh/pytest-dev/pytest/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/pytest-dev/pytest
|
||||
:alt: Code coverage Status
|
||||
|
||||
.. image:: https://travis-ci.org/pytest-dev/pytest.svg?branch=master
|
||||
:target: https://travis-ci.org/pytest-dev/pytest
|
||||
@@ -24,7 +26,7 @@
|
||||
:target: https://ci.appveyor.com/project/pytestbot/pytest
|
||||
|
||||
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
||||
:target: https://github.com/ambv/black
|
||||
:target: https://github.com/ambv/black
|
||||
|
||||
.. image:: https://www.codetriage.com/pytest-dev/pytest/badges/users.svg
|
||||
:target: https://www.codetriage.com/pytest-dev/pytest
|
||||
@@ -65,23 +67,23 @@ To execute it::
|
||||
========================== 1 failed in 0.04 seconds ===========================
|
||||
|
||||
|
||||
Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <http://docs.pytest.org/en/latest/getting-started.html#our-first-test-run>`_ for more examples.
|
||||
Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <https://docs.pytest.org/en/latest/getting-started.html#our-first-test-run>`_ for more examples.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Detailed info on failing `assert statements <http://docs.pytest.org/en/latest/assert.html>`_ (no need to remember ``self.assert*`` names);
|
||||
- Detailed info on failing `assert statements <https://docs.pytest.org/en/latest/assert.html>`_ (no need to remember ``self.assert*`` names);
|
||||
|
||||
- `Auto-discovery
|
||||
<http://docs.pytest.org/en/latest/goodpractices.html#python-test-discovery>`_
|
||||
<https://docs.pytest.org/en/latest/goodpractices.html#python-test-discovery>`_
|
||||
of test modules and functions;
|
||||
|
||||
- `Modular fixtures <http://docs.pytest.org/en/latest/fixture.html>`_ for
|
||||
- `Modular fixtures <https://docs.pytest.org/en/latest/fixture.html>`_ for
|
||||
managing small or parametrized long-lived test resources;
|
||||
|
||||
- Can run `unittest <http://docs.pytest.org/en/latest/unittest.html>`_ (or trial),
|
||||
`nose <http://docs.pytest.org/en/latest/nose.html>`_ test suites out of the box;
|
||||
- Can run `unittest <https://docs.pytest.org/en/latest/unittest.html>`_ (or trial),
|
||||
`nose <https://docs.pytest.org/en/latest/nose.html>`_ test suites out of the box;
|
||||
|
||||
- Python 2.7, Python 3.4+, PyPy 2.3, Jython 2.5 (untested);
|
||||
|
||||
@@ -91,7 +93,7 @@ Features
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
For full documentation, including installation, tutorials and PDF documents, please see http://docs.pytest.org.
|
||||
For full documentation, including installation, tutorials and PDF documents, please see https://docs.pytest.org/en/latest/.
|
||||
|
||||
|
||||
Bugs/Requests
|
||||
@@ -103,13 +105,13 @@ Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issue
|
||||
Changelog
|
||||
---------
|
||||
|
||||
Consult the `Changelog <http://docs.pytest.org/en/latest/changelog.html>`__ page for fixes and enhancements of each version.
|
||||
Consult the `Changelog <https://docs.pytest.org/en/latest/changelog.html>`__ page for fixes and enhancements of each version.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright Holger Krekel and others, 2004-2017.
|
||||
Copyright Holger Krekel and others, 2004-2018.
|
||||
|
||||
Distributed under the terms of the `MIT`_ license, pytest is free and open source software.
|
||||
|
||||
|
||||
56
appveyor.yml
56
appveyor.yml
@@ -1,34 +1,29 @@
|
||||
environment:
|
||||
COVERALLS_REPO_TOKEN:
|
||||
secure: 2NJ5Ct55cHJ9WEg3xbSqCuv0rdgzzb6pnzOIG5OkMbTndw3wOBrXntWFoQrXiMFi
|
||||
# this is pytest's token in coveralls.io, encrypted
|
||||
# using pytestbot account as detailed here:
|
||||
# https://www.appveyor.com/docs/build-configuration#secure-variables
|
||||
|
||||
matrix:
|
||||
# coveralls is not in the default env list
|
||||
- TOXENV: "coveralls"
|
||||
# note: please use "tox --listenvs" to populate the build matrix below
|
||||
- TOXENV: "linting"
|
||||
- TOXENV: "py27"
|
||||
- TOXENV: "py34"
|
||||
- TOXENV: "py35"
|
||||
- TOXENV: "py37"
|
||||
PYTEST_NO_COVERAGE: "1"
|
||||
- TOXENV: "linting,docs,doctesting"
|
||||
- TOXENV: "py36"
|
||||
- TOXENV: "py35"
|
||||
- TOXENV: "py34"
|
||||
- TOXENV: "pypy"
|
||||
- TOXENV: "py27-pexpect"
|
||||
- TOXENV: "py27-xdist"
|
||||
- TOXENV: "py27-trial"
|
||||
- TOXENV: "py27-numpy"
|
||||
PYTEST_NO_COVERAGE: "1"
|
||||
# Specialized factors for py27.
|
||||
- TOXENV: "py27-trial,py27-numpy,py27-nobyte"
|
||||
- TOXENV: "py27-pluggymaster"
|
||||
- TOXENV: "py36-pexpect"
|
||||
- TOXENV: "py36-xdist"
|
||||
- TOXENV: "py36-trial"
|
||||
- TOXENV: "py36-numpy"
|
||||
PYTEST_NO_COVERAGE: "1"
|
||||
- TOXENV: "py27-xdist"
|
||||
# Specialized factors for py36.
|
||||
- TOXENV: "py36-trial,py36-numpy"
|
||||
- TOXENV: "py36-pluggymaster"
|
||||
- TOXENV: "py27-nobyte"
|
||||
- TOXENV: "doctesting"
|
||||
- TOXENV: "py35-freeze"
|
||||
- TOXENV: "docs"
|
||||
PYTEST_NO_COVERAGE: "1"
|
||||
- TOXENV: "py36-freeze"
|
||||
PYTEST_NO_COVERAGE: "1"
|
||||
- TOXENV: "py36-xdist"
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
install:
|
||||
- echo Installed Pythons
|
||||
@@ -36,13 +31,24 @@ install:
|
||||
|
||||
- if "%TOXENV%" == "pypy" call scripts\install-pypy.bat
|
||||
|
||||
- C:\Python36\python -m pip install --upgrade pip
|
||||
- C:\Python36\python -m pip install --upgrade --pre tox
|
||||
|
||||
build: false # Not a C# project, build stuff at the test step instead.
|
||||
|
||||
before_test:
|
||||
- call scripts\prepare-coverage.bat
|
||||
|
||||
test_script:
|
||||
- call scripts\call-tox.bat
|
||||
- C:\Python36\python -m tox
|
||||
|
||||
on_success:
|
||||
- call scripts\upload-coverage.bat
|
||||
|
||||
cache:
|
||||
- '%LOCALAPPDATA%\pip\cache'
|
||||
- '%USERPROFILE%\.cache\pre-commit'
|
||||
|
||||
# We don't deploy anything on tags with AppVeyor, we use Travis instead, so we
|
||||
# might as well save resources
|
||||
skip_tags: true
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
|
||||
|
||||
# 10000 iterations, just for relative comparison
|
||||
# 2.7.5 3.3.2
|
||||
# FilesCompleter 75.1109 69.2116
|
||||
# FastFilesCompleter 0.7383 1.0760
|
||||
|
||||
import timeit
|
||||
|
||||
imports = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import py
|
||||
import six
|
||||
|
||||
for i in range(1000):
|
||||
py.builtin.exec_("def test_func_%d(): pass" % i)
|
||||
six.exec_("def test_func_%d(): pass" % i)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from six.moves import range
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@ Each file should be named like ``<ISSUE>.<TYPE>.rst``, where
|
||||
* ``feature``: new user facing features, like new command-line options and new behavior.
|
||||
* ``bugfix``: fixes a reported bug.
|
||||
* ``doc``: documentation improvement, like rewording an entire session or adding missing docs.
|
||||
* ``removal``: feature deprecation or removal.
|
||||
* ``deprecation``: feature deprecation.
|
||||
* ``removal``: feature removal.
|
||||
* ``vendor``: changes in packages vendored in pytest.
|
||||
* ``trivial``: fixing a small typo or internal change that might be noteworthy.
|
||||
|
||||
@@ -26,7 +27,7 @@ changelog using that instead.
|
||||
|
||||
If you are not sure what issue type to use, don't hesitate to ask in your PR.
|
||||
|
||||
Note that the ``towncrier`` tool will automatically
|
||||
reflow your text, so it will work best if you stick to a single paragraph, but multiple sentences and links are OK
|
||||
and encouraged. You can install ``towncrier`` and then run ``towncrier --draft``
|
||||
``towncrier`` preserves multiple paragraphs and formatting (code blocks, lists, and so on), but for entries
|
||||
other than ``features`` it is usually better to stick to a single paragraph to keep it concise. You can install
|
||||
``towncrier`` and then run ``towncrier --draft``
|
||||
if you want to get a preview of how your change will look in the final release notes.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{% if definitions[category]['showcontent'] %}
|
||||
{% for text, values in sections[section][category]|dictsort(by='value') %}
|
||||
{% set issue_joiner = joiner(', ') %}
|
||||
- {{ text }}{% if category != 'vendor' %} ({% for value in values|sort %}{{ issue_joiner() }}`{{ value }} <https://github.com/pytest-dev/pytest/issues/{{ value[1:] }}>`_{% endfor %}){% endif %}
|
||||
- {% for value in values|sort %}{{ issue_joiner() }}`{{ value }} <https://github.com/pytest-dev/pytest/issues/{{ value[1:] }}>`_{% endfor %}: {{ text }}
|
||||
|
||||
|
||||
{% endfor %}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
# flasky extensions. flasky pygments style based on tango style
|
||||
from pygments.style import Style
|
||||
from pygments.token import (
|
||||
Keyword,
|
||||
Name,
|
||||
Comment,
|
||||
String,
|
||||
Error,
|
||||
Number,
|
||||
Operator,
|
||||
Generic,
|
||||
Whitespace,
|
||||
Punctuation,
|
||||
Other,
|
||||
Literal,
|
||||
)
|
||||
from pygments.token import Comment
|
||||
from pygments.token import Error
|
||||
from pygments.token import Generic
|
||||
from pygments.token import Keyword
|
||||
from pygments.token import Literal
|
||||
from pygments.token import Name
|
||||
from pygments.token import Number
|
||||
from pygments.token import Operator
|
||||
from pygments.token import Other
|
||||
from pygments.token import Punctuation
|
||||
from pygments.token import String
|
||||
from pygments.token import Whitespace
|
||||
|
||||
|
||||
class FlaskyStyle(Style):
|
||||
|
||||
@@ -6,6 +6,21 @@ Release announcements
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
release-3.9.3
|
||||
release-3.9.2
|
||||
release-3.9.1
|
||||
release-3.9.0
|
||||
release-3.8.2
|
||||
release-3.8.1
|
||||
release-3.8.0
|
||||
release-3.7.4
|
||||
release-3.7.3
|
||||
release-3.7.2
|
||||
release-3.7.1
|
||||
release-3.7.0
|
||||
release-3.6.4
|
||||
release-3.6.3
|
||||
release-3.6.2
|
||||
release-3.6.1
|
||||
release-3.6.0
|
||||
release-3.5.1
|
||||
|
||||
@@ -23,7 +23,7 @@ a full list of details. A few feature highlights:
|
||||
called if the corresponding setup method succeeded.
|
||||
|
||||
- integrate tab-completion on command line options if you
|
||||
have `argcomplete <http://pypi.python.org/pypi/argcomplete>`_
|
||||
have `argcomplete <https://pypi.org/project/argcomplete/>`_
|
||||
configured.
|
||||
|
||||
- allow boolean expression directly with skipif/xfail
|
||||
|
||||
@@ -124,7 +124,7 @@ The py.test Development Team
|
||||
Thanks `@biern`_ for the PR.
|
||||
|
||||
* Fix `traceback style docs`_ to describe all of the available options
|
||||
(auto/long/short/line/native/no), with `auto` being the default since v2.6.
|
||||
(auto/long/short/line/native/no), with ``auto`` being the default since v2.6.
|
||||
Thanks `@hackebrot`_ for the PR.
|
||||
|
||||
* Fix (`#1422`_): junit record_xml_property doesn't allow multiple records
|
||||
|
||||
29
doc/en/announce/release-3.6.2.rst
Normal file
29
doc/en/announce/release-3.6.2.rst
Normal file
@@ -0,0 +1,29 @@
|
||||
pytest-3.6.2
|
||||
=======================================
|
||||
|
||||
pytest 3.6.2 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Alan Velasco
|
||||
* Alex Barbato
|
||||
* Anthony Sottile
|
||||
* Bartosz Cierocki
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Guoqiang Zhang
|
||||
* Hynek Schlawack
|
||||
* John T. Wodder II
|
||||
* Michael Käufl
|
||||
* Ronny Pfannschmidt
|
||||
* Samuel Dion-Girardeau
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
27
doc/en/announce/release-3.6.3.rst
Normal file
27
doc/en/announce/release-3.6.3.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
pytest-3.6.3
|
||||
=======================================
|
||||
|
||||
pytest 3.6.3 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* AdamEr8
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Jean-Paul Calderone
|
||||
* Jon Dufresne
|
||||
* Marcelo Duarte Trevisani
|
||||
* Ondřej Súkup
|
||||
* Ronny Pfannschmidt
|
||||
* T.E.A de Souza
|
||||
* Victor Maryama
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
24
doc/en/announce/release-3.6.4.rst
Normal file
24
doc/en/announce/release-3.6.4.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
pytest-3.6.4
|
||||
=======================================
|
||||
|
||||
pytest 3.6.4 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bernhard M. Wiedemann
|
||||
* Bruno Oliveira
|
||||
* Drew
|
||||
* E Hershey
|
||||
* Hugo Martins
|
||||
* Vlad Shcherbina
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
41
doc/en/announce/release-3.7.0.rst
Normal file
41
doc/en/announce/release-3.7.0.rst
Normal file
@@ -0,0 +1,41 @@
|
||||
pytest-3.7.0
|
||||
=======================================
|
||||
|
||||
The pytest team is proud to announce the 3.7.0 release!
|
||||
|
||||
pytest is a mature Python testing tool with more than a 2000 tests
|
||||
against itself, passing on many different interpreters and platforms.
|
||||
|
||||
This release contains a number of bugs fixes and improvements, so users are encouraged
|
||||
to take a look at the CHANGELOG:
|
||||
|
||||
http://doc.pytest.org/en/latest/changelog.html
|
||||
|
||||
For complete documentation, please visit:
|
||||
|
||||
http://docs.pytest.org
|
||||
|
||||
As usual, you can upgrade from pypi via:
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Alan
|
||||
* Alan Brammer
|
||||
* Ammar Najjar
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Jeffrey Rackauckas
|
||||
* Kale Kundert
|
||||
* Ronny Pfannschmidt
|
||||
* Serhii Mozghovyi
|
||||
* Tadek Teleżyński
|
||||
* Wil Cooley
|
||||
* abrammer
|
||||
* avirlrma
|
||||
* turturica
|
||||
|
||||
|
||||
Happy testing,
|
||||
The Pytest Development Team
|
||||
21
doc/en/announce/release-3.7.1.rst
Normal file
21
doc/en/announce/release-3.7.1.rst
Normal file
@@ -0,0 +1,21 @@
|
||||
pytest-3.7.1
|
||||
=======================================
|
||||
|
||||
pytest 3.7.1 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Kale Kundert
|
||||
* Ronny Pfannschmidt
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
25
doc/en/announce/release-3.7.2.rst
Normal file
25
doc/en/announce/release-3.7.2.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
pytest-3.7.2
|
||||
=======================================
|
||||
|
||||
pytest 3.7.2 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Josh Holland
|
||||
* Ronny Pfannschmidt
|
||||
* Sankt Petersbug
|
||||
* Wes Thomas
|
||||
* turturica
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
32
doc/en/announce/release-3.7.3.rst
Normal file
32
doc/en/announce/release-3.7.3.rst
Normal file
@@ -0,0 +1,32 @@
|
||||
pytest-3.7.3
|
||||
=======================================
|
||||
|
||||
pytest 3.7.3 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Andrew Champion
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Gandalf Saxe
|
||||
* Jennifer Rinker
|
||||
* Natan Lao
|
||||
* Ondřej Súkup
|
||||
* Ronny Pfannschmidt
|
||||
* Sankt Petersbug
|
||||
* Tyler Richard
|
||||
* Victor Maryama
|
||||
* Vlad Shcherbina
|
||||
* turturica
|
||||
* wim glenn
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
22
doc/en/announce/release-3.7.4.rst
Normal file
22
doc/en/announce/release-3.7.4.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
pytest-3.7.4
|
||||
=======================================
|
||||
|
||||
pytest 3.7.4 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Jiri Kuncar
|
||||
* Steve Piercy
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
38
doc/en/announce/release-3.8.0.rst
Normal file
38
doc/en/announce/release-3.8.0.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
pytest-3.8.0
|
||||
=======================================
|
||||
|
||||
The pytest team is proud to announce the 3.8.0 release!
|
||||
|
||||
pytest is a mature Python testing tool with more than a 2000 tests
|
||||
against itself, passing on many different interpreters and platforms.
|
||||
|
||||
This release contains a number of bugs fixes and improvements, so users are encouraged
|
||||
to take a look at the CHANGELOG:
|
||||
|
||||
https://docs.pytest.org/en/latest/changelog.html
|
||||
|
||||
For complete documentation, please visit:
|
||||
|
||||
https://docs.pytest.org/en/latest/
|
||||
|
||||
As usual, you can upgrade from pypi via:
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* CrazyMerlyn
|
||||
* Daniel Hahler
|
||||
* Fabio Zadrozny
|
||||
* Jeffrey Rackauckas
|
||||
* Ronny Pfannschmidt
|
||||
* Virgil Dupras
|
||||
* dhirensr
|
||||
* hoefling
|
||||
* wim glenn
|
||||
|
||||
|
||||
Happy testing,
|
||||
The Pytest Development Team
|
||||
25
doc/en/announce/release-3.8.1.rst
Normal file
25
doc/en/announce/release-3.8.1.rst
Normal file
@@ -0,0 +1,25 @@
|
||||
pytest-3.8.1
|
||||
=======================================
|
||||
|
||||
pytest 3.8.1 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Ankit Goel
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Maximilian Albert
|
||||
* Ronny Pfannschmidt
|
||||
* William Jamir Silva
|
||||
* wim glenn
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
28
doc/en/announce/release-3.8.2.rst
Normal file
28
doc/en/announce/release-3.8.2.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
pytest-3.8.2
|
||||
=======================================
|
||||
|
||||
pytest 3.8.2 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Ankit Goel
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Denis Otkidach
|
||||
* Harry Percival
|
||||
* Jeffrey Rackauckas
|
||||
* Jose Carlos Menezes
|
||||
* Ronny Pfannschmidt
|
||||
* Zac-HD
|
||||
* iwanb
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
43
doc/en/announce/release-3.9.0.rst
Normal file
43
doc/en/announce/release-3.9.0.rst
Normal file
@@ -0,0 +1,43 @@
|
||||
pytest-3.9.0
|
||||
=======================================
|
||||
|
||||
The pytest team is proud to announce the 3.9.0 release!
|
||||
|
||||
pytest is a mature Python testing tool with more than a 2000 tests
|
||||
against itself, passing on many different interpreters and platforms.
|
||||
|
||||
This release contains a number of bugs fixes and improvements, so users are encouraged
|
||||
to take a look at the CHANGELOG:
|
||||
|
||||
https://docs.pytest.org/en/latest/changelog.html
|
||||
|
||||
For complete documentation, please visit:
|
||||
|
||||
https://docs.pytest.org/en/latest/
|
||||
|
||||
As usual, you can upgrade from pypi via:
|
||||
|
||||
pip install -U pytest
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Andrea Cimatoribus
|
||||
* Ankit Goel
|
||||
* Anthony Sottile
|
||||
* Ben Eyal
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Jeffrey Rackauckas
|
||||
* Jose Carlos Menezes
|
||||
* Kyle Altendorf
|
||||
* Niklas JQ
|
||||
* Palash Chatterjee
|
||||
* Ronny Pfannschmidt
|
||||
* Thomas Hess
|
||||
* Thomas Hisch
|
||||
* Tomer Keren
|
||||
* Victor Maryama
|
||||
|
||||
|
||||
Happy testing,
|
||||
The Pytest Development Team
|
||||
20
doc/en/announce/release-3.9.1.rst
Normal file
20
doc/en/announce/release-3.9.1.rst
Normal file
@@ -0,0 +1,20 @@
|
||||
pytest-3.9.1
|
||||
=======================================
|
||||
|
||||
pytest 3.9.1 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Bruno Oliveira
|
||||
* Ronny Pfannschmidt
|
||||
* Thomas Hisch
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
23
doc/en/announce/release-3.9.2.rst
Normal file
23
doc/en/announce/release-3.9.2.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
pytest-3.9.2
|
||||
=======================================
|
||||
|
||||
pytest 3.9.2 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Ankit Goel
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Ronny Pfannschmidt
|
||||
* Vincent Barbaresi
|
||||
* ykantor
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
24
doc/en/announce/release-3.9.3.rst
Normal file
24
doc/en/announce/release-3.9.3.rst
Normal file
@@ -0,0 +1,24 @@
|
||||
pytest-3.9.3
|
||||
=======================================
|
||||
|
||||
pytest 3.9.3 has just been released to PyPI.
|
||||
|
||||
This is a bug-fix release, being a drop-in replacement. To upgrade::
|
||||
|
||||
pip install --upgrade pytest
|
||||
|
||||
The full changelog is available at https://docs.pytest.org/en/latest/changelog.html.
|
||||
|
||||
Thanks to all who contributed to this release, among them:
|
||||
|
||||
* Andreas Profous
|
||||
* Ankit Goel
|
||||
* Anthony Sottile
|
||||
* Bruno Oliveira
|
||||
* Daniel Hahler
|
||||
* Jon Dufresne
|
||||
* Ronny Pfannschmidt
|
||||
|
||||
|
||||
Happy testing,
|
||||
The pytest Development Team
|
||||
@@ -91,7 +91,7 @@ In the context manager form you may use the keyword argument
|
||||
``message`` to specify a custom failure message::
|
||||
|
||||
>>> with raises(ZeroDivisionError, message="Expecting ZeroDivisionError"):
|
||||
... pass
|
||||
... pass
|
||||
... Failed: Expecting ZeroDivisionError
|
||||
|
||||
If you want to write test code that works on Python 2.4 as well,
|
||||
@@ -264,8 +264,12 @@ Advanced assertion introspection
|
||||
Reporting details about a failing assertion is achieved by rewriting assert
|
||||
statements before they are run. Rewritten assert statements put introspection
|
||||
information into the assertion failure message. ``pytest`` only rewrites test
|
||||
modules directly discovered by its test collection process, so asserts in
|
||||
supporting modules which are not themselves test modules will not be rewritten.
|
||||
modules directly discovered by its test collection process, so **asserts in
|
||||
supporting modules which are not themselves test modules will not be rewritten**.
|
||||
|
||||
You can manually enable assertion rewriting for an imported module by calling
|
||||
`register_assert_rewrite <https://docs.pytest.org/en/latest/writing_plugins.html#assertion-rewriting>`_
|
||||
before you import it (a good place to do that is in ``conftest.py``).
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
@@ -7,14 +7,16 @@ Keeping backwards compatibility has a very high priority in the pytest project.
|
||||
|
||||
With the pytest 3.0 release we introduced a clear communication scheme for when we will actually remove the old busted joint and politely ask you to use the new hotness instead, while giving you enough time to adjust your tests or raise concerns if there are valid reasons to keep deprecated functionality around.
|
||||
|
||||
To communicate changes we are already issuing deprecation warnings, but they are not displayed by default. In pytest 3.0 we changed the default setting so that pytest deprecation warnings are displayed if not explicitly silenced (with ``--disable-pytest-warnings``).
|
||||
To communicate changes we issue deprecation warnings using a custom warning hierarchy (see :ref:`internal-warnings`). These warnings may be suppressed using the standard means: ``-W`` command-line flag or ``filterwarnings`` ini options (see :ref:`warnings`), but we suggest to use these sparingly and temporarily, and heed the warnings when possible.
|
||||
|
||||
We will only remove deprecated functionality in major releases (e.g. if we deprecate something in 3.0 we will remove it in 4.0), and keep it around for at least two minor releases (e.g. if we deprecate something in 3.9 and 4.0 is the next release, we will not remove it in 4.0 but in 5.0).
|
||||
We will only start the removal of deprecated functionality in major releases (e.g. if we deprecate something in 3.0 we will start to remove it in 4.0), and keep it around for at least two minor releases (e.g. if we deprecate something in 3.9 and 4.0 is the next release, we start to remove it in 5.0, not in 4.0).
|
||||
|
||||
When the deprecation expires (e.g. 4.0 is released), we won't remove the deprecated functionality immediately, but will use the standard warning filters to turn them into **errors** by default. This approach makes it explicit that removal is imminent, and still gives you time to turn the deprecated feature into a warning instead of an error so it can be dealt with in your own time. In the next minor release (e.g. 4.1), the feature will be effectively removed.
|
||||
|
||||
|
||||
Deprecation Roadmap
|
||||
-------------------
|
||||
|
||||
We track deprecation and removal of features using milestones and the `deprecation <https://github.com/pytest-dev/pytest/issues?q=label%3A%22type%3A+deprecation%22>`_ and `removal <https://github.com/pytest-dev/pytest/labels/type%3A%20removal>`_ labels on GitHub.
|
||||
Features currently deprecated and removed in previous releases can be found in :ref:`deprecations`.
|
||||
|
||||
Following our deprecation policy, after starting issuing deprecation warnings we keep features for *at least* two minor versions before considering removal.
|
||||
We track future deprecation and removal of features using milestones and the `deprecation <https://github.com/pytest-dev/pytest/issues?q=label%3A%22type%3A+deprecation%22>`_ and `removal <https://github.com/pytest-dev/pytest/labels/type%3A%20removal>`_ labels on GitHub.
|
||||
|
||||
@@ -75,7 +75,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
caplog
|
||||
Access and control log capturing.
|
||||
|
||||
Captured logs are available through the following methods::
|
||||
Captured logs are available through the following properties/methods::
|
||||
|
||||
* caplog.text -> string containing formatted log output
|
||||
* caplog.records -> list of logging.LogRecord instances
|
||||
@@ -90,7 +90,7 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
monkeypatch.setitem(mapping, name, value)
|
||||
monkeypatch.delitem(obj, name, raising=True)
|
||||
monkeypatch.setenv(name, value, prepend=False)
|
||||
monkeypatch.delenv(name, value, raising=True)
|
||||
monkeypatch.delenv(name, raising=True)
|
||||
monkeypatch.syspath_prepend(path)
|
||||
monkeypatch.chdir(path)
|
||||
|
||||
@@ -104,7 +104,9 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
See http://docs.python.org/library/warnings.html for information
|
||||
on warning categories.
|
||||
tmpdir_factory
|
||||
Return a TempdirFactory instance for the test session.
|
||||
Return a :class:`_pytest.tmpdir.TempdirFactory` instance for the test session.
|
||||
tmp_path_factory
|
||||
Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
|
||||
tmpdir
|
||||
Return a temporary directory path object
|
||||
which is unique to each test function invocation,
|
||||
@@ -113,6 +115,16 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
|
||||
path object.
|
||||
|
||||
.. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
|
||||
tmp_path
|
||||
Return a temporary directory path object
|
||||
which is unique to each test function invocation,
|
||||
created as a sub directory of the base temporary
|
||||
directory. The returned object is a :class:`pathlib.Path`
|
||||
object.
|
||||
|
||||
.. note::
|
||||
|
||||
in python < 3.6 this is a pathlib2.Path
|
||||
|
||||
no tests ran in 0.12 seconds
|
||||
|
||||
|
||||
@@ -162,8 +162,8 @@ When no tests failed in the last run, or when no cached ``lastfailed`` data was
|
||||
found, ``pytest`` can be configured either to run all of the tests or no tests,
|
||||
using the ``--last-failed-no-failures`` option, which takes one of the following values::
|
||||
|
||||
pytest --last-failed-no-failures all # run all tests (default behavior)
|
||||
pytest --last-failed-no-failures none # run no tests and exit
|
||||
pytest --last-failed --last-failed-no-failures all # run all tests (default behavior)
|
||||
pytest --last-failed --last-failed-no-failures none # run no tests and exit
|
||||
|
||||
The new config.cache object
|
||||
--------------------------------
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
|
||||
.. _changelog:
|
||||
|
||||
Changelog history
|
||||
=================================
|
||||
|
||||
.. include:: ../../CHANGELOG.rst
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
def test_build_docs(tmpdir):
|
||||
doctrees = tmpdir.join("doctrees")
|
||||
htmldir = tmpdir.join("html")
|
||||
subprocess.check_call(
|
||||
["sphinx-build", "-W", "-bhtml", "-d", str(doctrees), ".", str(htmldir)]
|
||||
)
|
||||
|
||||
|
||||
def test_linkcheck(tmpdir):
|
||||
doctrees = tmpdir.join("doctrees")
|
||||
htmldir = tmpdir.join("html")
|
||||
subprocess.check_call(
|
||||
["sphinx-build", "-blinkcheck", "-d", str(doctrees), ".", str(htmldir)]
|
||||
)
|
||||
@@ -10,17 +10,15 @@
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
# The short X.Y version.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
|
||||
from _pytest import __version__ as version
|
||||
|
||||
@@ -65,7 +63,7 @@ master_doc = "contents"
|
||||
# General information about the project.
|
||||
project = u"pytest"
|
||||
year = datetime.datetime.utcnow().year
|
||||
copyright = u"2015–{} , holger krekel and pytest-dev team".format(year)
|
||||
copyright = u"2015–2018 , holger krekel and pytest-dev team"
|
||||
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
@@ -329,7 +327,7 @@ texinfo_documents = [
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {"python": ("http://docs.python.org/3", None)}
|
||||
intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}
|
||||
|
||||
|
||||
def setup(app):
|
||||
|
||||
@@ -39,6 +39,7 @@ Full pytest documentation
|
||||
bash-completion
|
||||
|
||||
backwards-compatibility
|
||||
deprecations
|
||||
historical-notes
|
||||
license
|
||||
contributing
|
||||
|
||||
@@ -32,7 +32,7 @@ Here's a summary what ``pytest`` uses ``rootdir`` for:
|
||||
class name, function name and parametrization (if any).
|
||||
|
||||
* Is used by plugins as a stable location to store project/test run specific information;
|
||||
for example, the internal :ref:`cache <cache>` plugin creates a ``.cache`` subdirectory
|
||||
for example, the internal :ref:`cache <cache>` plugin creates a ``.pytest_cache`` subdirectory
|
||||
in ``rootdir`` to store its cross-test run state.
|
||||
|
||||
Important to emphasize that ``rootdir`` is **NOT** used to modify ``sys.path``/``PYTHONPATH`` or
|
||||
@@ -139,7 +139,7 @@ line options while the environment is in use::
|
||||
|
||||
Here's how the command-line is built in the presence of ``addopts`` or the environment variable::
|
||||
|
||||
<pytest.ini:addopts> $PYTEST_ADDOTPS <extra command-line arguments>
|
||||
<pytest.ini:addopts> $PYTEST_ADDOPTS <extra command-line arguments>
|
||||
|
||||
So if the user executes in the command-line::
|
||||
|
||||
|
||||
386
doc/en/deprecations.rst
Normal file
386
doc/en/deprecations.rst
Normal file
@@ -0,0 +1,386 @@
|
||||
.. _deprecations:
|
||||
|
||||
Deprecations and Removals
|
||||
=========================
|
||||
|
||||
This page lists all pytest features that are currently deprecated or have been removed in past major releases.
|
||||
The objective is to give users a clear rationale why a certain feature has been removed, and what alternatives
|
||||
should be used instead.
|
||||
|
||||
Deprecated Features
|
||||
-------------------
|
||||
|
||||
Below is a complete list of all pytest features which are considered deprecated. Using those features will issue
|
||||
:class:`_pytest.warning_types.PytestWarning` or subclasses, which can be filtered using
|
||||
:ref:`standard warning filters <warnings>`.
|
||||
|
||||
Internal classes accessed through ``Node``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances now issue
|
||||
this warning::
|
||||
|
||||
usage of Function.Module is deprecated, please use pytest.Module instead
|
||||
|
||||
Users should just ``import pytest`` and access those objects using the ``pytest`` module.
|
||||
|
||||
This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.
|
||||
|
||||
``cached_setup``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
``request.cached_setup`` was the precursor of the setup/teardown mechanism available to fixtures.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def db_session():
|
||||
return request.cached_setup(
|
||||
setup=Session.create, teardown=lambda session: session.close(), scope="module"
|
||||
)
|
||||
|
||||
This should be updated to make use of standard fixture mechanisms:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def db_session():
|
||||
session = Session.create()
|
||||
yield session
|
||||
session.close()
|
||||
|
||||
|
||||
You can consult `funcarg comparison section in the docs <https://docs.pytest.org/en/latest/funcarg_compare.html>`_ for
|
||||
more information.
|
||||
|
||||
This has been documented as deprecated for years, but only now we are actually emitting deprecation warnings.
|
||||
|
||||
|
||||
Using ``Class`` in custom Collectors
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
Using objects named ``"Class"`` as a way to customize the type of nodes that are collected in ``Collector``
|
||||
subclasses has been deprecated. Users instead should use ``pytest_pycollect_makeitem`` to customize node types during
|
||||
collection.
|
||||
|
||||
This issue should affect only advanced plugins who create new collection types, so if you see this warning
|
||||
message please contact the authors so they can change the code.
|
||||
|
||||
|
||||
``Config.warn`` and ``Node.warn``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.8
|
||||
|
||||
Those methods were part of the internal pytest warnings system, but since ``3.8`` pytest is using the builtin warning
|
||||
system for its own warnings, so those two functions are now deprecated.
|
||||
|
||||
``Config.warn`` should be replaced by calls to the standard ``warnings.warn``, example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
config.warn("C1", "some warning")
|
||||
|
||||
Becomes:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
warnings.warn(pytest.PytestWarning("some warning"))
|
||||
|
||||
``Node.warn`` now supports two signatures:
|
||||
|
||||
* ``node.warn(PytestWarning("some message"))``: is now the **recommended** way to call this function.
|
||||
The warning instance must be a PytestWarning or subclass.
|
||||
|
||||
* ``node.warn("CI", "some message")``: this code/message form is now **deprecated** and should be converted to the warning instance form above.
|
||||
|
||||
|
||||
``pytest_namespace``
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.7
|
||||
|
||||
This hook is deprecated because it greatly complicates the pytest internals regarding configuration and initialization, making some
|
||||
bug fixes and refactorings impossible.
|
||||
|
||||
Example of usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class MySymbol:
|
||||
...
|
||||
|
||||
|
||||
def pytest_namespace():
|
||||
return {"my_symbol": MySymbol()}
|
||||
|
||||
|
||||
Plugin authors relying on this hook should instead require that users now import the plugin modules directly (with an appropriate public API).
|
||||
|
||||
As a stopgap measure, plugin authors may still inject their names into pytest's namespace, usually during ``pytest_configure``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_configure():
|
||||
pytest.my_symbol = MySymbol()
|
||||
|
||||
|
||||
|
||||
Calling fixtures directly
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.7
|
||||
|
||||
Calling a fixture function directly, as opposed to request them in a test function, is deprecated.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def cell():
|
||||
return ...
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def full_cell():
|
||||
cell = cell()
|
||||
cell.make_full()
|
||||
return cell
|
||||
|
||||
This is a great source of confusion to new users, which will often call the fixture functions and request them from test functions interchangeably, which breaks the fixture resolution model.
|
||||
|
||||
In those cases just request the function directly in the dependent fixture:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def cell():
|
||||
return ...
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def full_cell(cell):
|
||||
cell.make_full()
|
||||
return cell
|
||||
|
||||
``Node.get_marker``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.6
|
||||
|
||||
As part of a large :ref:`marker-revamp`, :meth:`_pytest.nodes.Node.get_marker` is deprecated. See
|
||||
:ref:`the documentation <update marker code>` on tips on how to update your code.
|
||||
|
||||
|
||||
record_xml_property
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.5
|
||||
|
||||
The ``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``, which
|
||||
can be used by other consumers (for example ``pytest-html``) to obtain custom information about the test run.
|
||||
|
||||
This is just a matter of renaming the fixture as the API is the same:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_foo(record_xml_property):
|
||||
...
|
||||
|
||||
Change to:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_foo(record_property):
|
||||
...
|
||||
|
||||
pytest_plugins in non-top-level conftest files
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.5
|
||||
|
||||
Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py
|
||||
files because they will activate referenced plugins *globally*, which is surprising because for all other pytest
|
||||
features ``conftest.py`` files are only *active* for tests at or below it.
|
||||
|
||||
Metafunc.addcall
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.3
|
||||
|
||||
:meth:`_pytest.python.Metafunc.addcall` was a precursor to the current parametrized mechanism. Users should use
|
||||
:meth:`_pytest.python.Metafunc.parametrize` instead.
|
||||
|
||||
marks in ``pytest.mark.parametrize``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.2
|
||||
|
||||
Applying marks to values of a ``pytest.mark.parametrize`` call is now deprecated. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a, b", [(3, 9), pytest.mark.xfail(reason="flaky")(6, 36), (10, 100)]
|
||||
)
|
||||
def test_foo(a, b):
|
||||
...
|
||||
|
||||
This code applies the ``pytest.mark.xfail(reason="flaky")`` mark to the ``(6, 36)`` value of the above parametrization
|
||||
call.
|
||||
|
||||
This was considered hard to read and understand, and also its implementation presented problems to the code preventing
|
||||
further internal improvements in the marks architecture.
|
||||
|
||||
To update the code, use ``pytest.param``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"a, b",
|
||||
[(3, 9), pytest.param((6, 36), marks=pytest.mark.xfail(reason="flaky")), (10, 100)],
|
||||
)
|
||||
def test_foo(a, b):
|
||||
...
|
||||
|
||||
|
||||
|
||||
Passing command-line string to ``pytest.main()``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
Passing a command-line string to ``pytest.main()`` is deprecated:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytest.main("-v -s")
|
||||
|
||||
Pass a list instead:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
pytest.main(["-v", "-s"])
|
||||
|
||||
|
||||
By passing a string, users expect that pytest will interpret that command-line using the shell rules they are working
|
||||
on (for example ``bash`` or ``Powershell``), but this is very hard/impossible to do in a portable way.
|
||||
|
||||
|
||||
``yield`` tests
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
pytest supports ``yield``-style tests, where a test function actually ``yield`` functions and values
|
||||
that are then turned into proper test methods. Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def check(x, y):
|
||||
assert x ** x == y
|
||||
|
||||
|
||||
def test_squared():
|
||||
yield check, 2, 4
|
||||
yield check, 3, 9
|
||||
|
||||
This would result into two actual test functions being generated.
|
||||
|
||||
This form of test function doesn't support fixtures properly, and users should switch to ``pytest.mark.parametrize``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.parametrize("x, y", [(2, 4), (3, 9)])
|
||||
def test_squared(x, y):
|
||||
assert x ** x == y
|
||||
|
||||
|
||||
``pytest_funcarg__`` prefix
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
In very early pytest versions fixtures could be defined using the ``pytest_funcarg__`` prefix:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def pytest_funcarg__data():
|
||||
return SomeData()
|
||||
|
||||
Switch over to the ``@pytest.fixture`` decorator:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture
|
||||
def data():
|
||||
return SomeData()
|
||||
|
||||
[pytest] section in setup.cfg files
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
``[pytest]`` sections in ``setup.cfg`` files should now be named ``[tool:pytest]``
|
||||
to avoid conflicts with other distutils commands.
|
||||
|
||||
Result log (``--result-log``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. deprecated:: 3.0
|
||||
|
||||
The ``--resultlog`` command line option has been deprecated: it is little used
|
||||
and there are more modern and better alternatives, for example `pytest-tap <https://tappy.readthedocs.io/en/latest/>`_.
|
||||
|
||||
Removed Features
|
||||
----------------
|
||||
|
||||
As stated in our :ref:`backwards-compatibility` policy, deprecated features are removed only in major releases after
|
||||
an appropriate period of deprecation has passed.
|
||||
|
||||
|
||||
Reinterpretation mode (``--assert=reinterp``)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 3.0.*
|
||||
|
||||
Reinterpretation mode has now been removed and only plain and rewrite
|
||||
mode are available, consequently the ``--assert=reinterp`` option is
|
||||
no longer available. This also means files imported from plugins or
|
||||
``conftest.py`` will not benefit from improved assertions by
|
||||
default, you should use ``pytest.register_assert_rewrite()`` to
|
||||
explicitly turn on assertion rewriting for those files.
|
||||
|
||||
Removed command-line options
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 3.0.*
|
||||
|
||||
The following deprecated commandline options were removed:
|
||||
|
||||
* ``--genscript``: no longer supported;
|
||||
* ``--no-assert``: use ``--assert=plain`` instead;
|
||||
* ``--nomagic``: use ``--assert=plain`` instead;
|
||||
* ``--report``: use ``-r`` instead;
|
||||
|
||||
py.test-X* entry points
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
*Removed in version 3.0.*
|
||||
|
||||
Removed all ``py.test-X*`` entry points. The versioned, suffixed entry points
|
||||
were never documented and a leftover from a pre-virtualenv era. These entry
|
||||
points also created broken entry points in wheels, so removing them also
|
||||
removes a source of confusion for users.
|
||||
@@ -39,6 +39,11 @@ avoid creating labels just for the sake of creating them.
|
||||
|
||||
Each label should include a description in the GitHub's interface stating its purpose.
|
||||
|
||||
Labels are managed using `labels <https://github.com/hackebrot/labels>`_. All the labels in the repository
|
||||
are kept in ``.github/labels.toml``, so any changes should be via PRs to that file.
|
||||
After a PR is accepted and merged, one of the maintainers must manually synchronize the labels file with the
|
||||
GitHub repository.
|
||||
|
||||
Temporary labels
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from pytest import raises
|
||||
import six
|
||||
|
||||
import _pytest._code
|
||||
import py
|
||||
from pytest import raises
|
||||
|
||||
|
||||
def otherfunc(a, b):
|
||||
@@ -25,9 +26,7 @@ def pytest_generate_tests(metafunc):
|
||||
|
||||
|
||||
class TestFailing(object):
|
||||
|
||||
def test_simple(self):
|
||||
|
||||
def f():
|
||||
return 42
|
||||
|
||||
@@ -40,7 +39,6 @@ class TestFailing(object):
|
||||
otherfunc_multi(42, 6 * 9)
|
||||
|
||||
def test_not(self):
|
||||
|
||||
def f():
|
||||
return 42
|
||||
|
||||
@@ -48,7 +46,6 @@ class TestFailing(object):
|
||||
|
||||
|
||||
class TestSpecialisedExplanations(object):
|
||||
|
||||
def test_eq_text(self):
|
||||
assert "spam" == "eggs"
|
||||
|
||||
@@ -106,7 +103,6 @@ class TestSpecialisedExplanations(object):
|
||||
|
||||
|
||||
def test_attribute():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -115,7 +111,6 @@ def test_attribute():
|
||||
|
||||
|
||||
def test_attribute_instance():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -123,9 +118,7 @@ def test_attribute_instance():
|
||||
|
||||
|
||||
def test_attribute_failure():
|
||||
|
||||
class Foo(object):
|
||||
|
||||
def _get_b(self):
|
||||
raise Exception("Failed to get attrib")
|
||||
|
||||
@@ -136,7 +129,6 @@ def test_attribute_failure():
|
||||
|
||||
|
||||
def test_attribute_multiple():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -151,7 +143,6 @@ def globf(x):
|
||||
|
||||
|
||||
class TestRaises(object):
|
||||
|
||||
def test_raises(self):
|
||||
s = "qwe" # NOQA
|
||||
raises(TypeError, "int(s)")
|
||||
@@ -187,15 +178,13 @@ def test_dynamic_compile_shows_nicely():
|
||||
name = "abc-123"
|
||||
module = imp.new_module(name)
|
||||
code = _pytest._code.compile(src, name, "exec")
|
||||
py.builtin.exec_(code, module.__dict__)
|
||||
six.exec_(code, module.__dict__)
|
||||
sys.modules[name] = module
|
||||
module.foo()
|
||||
|
||||
|
||||
class TestMoreErrors(object):
|
||||
|
||||
def test_complex_error(self):
|
||||
|
||||
def f():
|
||||
return 44
|
||||
|
||||
@@ -218,7 +207,6 @@ class TestMoreErrors(object):
|
||||
assert s.startswith(g)
|
||||
|
||||
def test_startswith_nested(self):
|
||||
|
||||
def f():
|
||||
return "123"
|
||||
|
||||
@@ -246,9 +234,7 @@ class TestMoreErrors(object):
|
||||
|
||||
|
||||
class TestCustomAssertMsg(object):
|
||||
|
||||
def test_single_line(self):
|
||||
|
||||
class A(object):
|
||||
a = 1
|
||||
|
||||
@@ -256,17 +242,15 @@ class TestCustomAssertMsg(object):
|
||||
assert A.a == b, "A.a appears not to be b"
|
||||
|
||||
def test_multiline(self):
|
||||
|
||||
class A(object):
|
||||
a = 1
|
||||
|
||||
b = 2
|
||||
assert (
|
||||
A.a == b
|
||||
), "A.a appears not to be b\n" "or does not appear to be b\none of those"
|
||||
), "A.a appears not to be b\nor does not appear to be b\none of those"
|
||||
|
||||
def test_custom_repr(self):
|
||||
|
||||
class JSON(object):
|
||||
a = 1
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
import py
|
||||
|
||||
import pytest
|
||||
|
||||
mydir = py.path.local(__file__).dirpath()
|
||||
|
||||
|
||||
@@ -10,4 +11,4 @@ def pytest_runtest_setup(item):
|
||||
return
|
||||
mod = item.getparent(pytest.Module).obj
|
||||
if hasattr(mod, "hello"):
|
||||
print("mod.hello %r" % (mod.hello,))
|
||||
print("mod.hello {!r}".format(mod.hello))
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
hello = "world"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
|
||||
import py
|
||||
|
||||
failure_demo = py.path.local(__file__).dirpath("failure_demo.py")
|
||||
pytest_plugins = "pytester",
|
||||
pytest_plugins = ("pytester",)
|
||||
|
||||
|
||||
def test_failure_demo_fails_properly(testdir):
|
||||
|
||||
@@ -3,7 +3,6 @@ def setup_module(module):
|
||||
|
||||
|
||||
class TestStateFullThing(object):
|
||||
|
||||
def setup_class(cls):
|
||||
cls.classcount += 1
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -10,7 +9,6 @@ def setup(request):
|
||||
|
||||
|
||||
class CostlySetup(object):
|
||||
|
||||
def __init__(self):
|
||||
import time
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ You can then restrict a test run to only run tests marked with ``webtest``::
|
||||
|
||||
$ pytest -v -m webtest
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items / 3 deselected
|
||||
@@ -44,7 +44,7 @@ Or the inverse, running all tests except the webtest ones::
|
||||
|
||||
$ pytest -v -m "not webtest"
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items / 1 deselected
|
||||
@@ -64,7 +64,7 @@ tests based on their module, class, method, or function name::
|
||||
|
||||
$ pytest -v test_server.py::TestClass::test_method
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 1 item
|
||||
@@ -77,7 +77,7 @@ You can also select on the class::
|
||||
|
||||
$ pytest -v test_server.py::TestClass
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 1 item
|
||||
@@ -90,7 +90,7 @@ Or select multiple nodes::
|
||||
|
||||
$ pytest -v test_server.py::TestClass test_server.py::test_send_http
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 2 items
|
||||
@@ -128,7 +128,7 @@ select tests based on their names::
|
||||
|
||||
$ pytest -v -k http # running with the above defined example module
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items / 3 deselected
|
||||
@@ -141,7 +141,7 @@ And you can also run all tests except the ones that match the keyword::
|
||||
|
||||
$ pytest -k "not send_http" -v
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items / 1 deselected
|
||||
@@ -156,7 +156,7 @@ Or to select "http" and "quick" tests::
|
||||
|
||||
$ pytest -k "http or quick" -v
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 4 items / 2 deselected
|
||||
@@ -200,15 +200,17 @@ You can ask which markers exist for your test suite - the list includes our just
|
||||
$ pytest --markers
|
||||
@pytest.mark.webtest: mark a test as a webtest.
|
||||
|
||||
@pytest.mark.filterwarnings(warning): add a warning filter to the given test. see https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings
|
||||
|
||||
@pytest.mark.skip(reason=None): skip the given test function with an optional reason. Example: skip(reason="no way of currently testing this") skips the test.
|
||||
|
||||
@pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html
|
||||
@pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see https://docs.pytest.org/en/latest/skipping.html
|
||||
|
||||
@pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html
|
||||
@pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See https://docs.pytest.org/en/latest/skipping.html
|
||||
|
||||
@pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples.
|
||||
@pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see https://docs.pytest.org/en/latest/parametrize.html for more info and examples.
|
||||
|
||||
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures
|
||||
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see https://docs.pytest.org/en/latest/fixture.html#usefixtures
|
||||
|
||||
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
|
||||
|
||||
@@ -299,10 +301,10 @@ Skip and xfail marks can also be applied in this way, see :ref:`skip/xfail with
|
||||
.. note::
|
||||
|
||||
If the data you are parametrizing happen to be single callables, you need to be careful
|
||||
when marking these items. `pytest.mark.xfail(my_func)` won't work because it's also the
|
||||
when marking these items. ``pytest.mark.xfail(my_func)`` won't work because it's also the
|
||||
signature of a function being decorated. To resolve this ambiguity, you need to pass a
|
||||
reason argument:
|
||||
`pytest.mark.xfail(func_bar, reason="Issue#7")`.
|
||||
``pytest.mark.xfail(func_bar, reason="Issue#7")``.
|
||||
|
||||
|
||||
.. _`adding a custom marker from a plugin`:
|
||||
@@ -374,15 +376,17 @@ The ``--markers`` option always gives you a list of available markers::
|
||||
$ pytest --markers
|
||||
@pytest.mark.env(name): mark test to run only on named environment
|
||||
|
||||
@pytest.mark.filterwarnings(warning): add a warning filter to the given test. see https://docs.pytest.org/en/latest/warnings.html#pytest-mark-filterwarnings
|
||||
|
||||
@pytest.mark.skip(reason=None): skip the given test function with an optional reason. Example: skip(reason="no way of currently testing this") skips the test.
|
||||
|
||||
@pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see http://pytest.org/latest/skipping.html
|
||||
@pytest.mark.skipif(condition): skip the given test function if eval(condition) results in a True value. Evaluation happens within the module global context. Example: skipif('sys.platform == "win32"') skips the test if we are on the win32 platform. see https://docs.pytest.org/en/latest/skipping.html
|
||||
|
||||
@pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See http://pytest.org/latest/skipping.html
|
||||
@pytest.mark.xfail(condition, reason=None, run=True, raises=None, strict=False): mark the test function as an expected failure if eval(condition) has a True value. Optionally specify a reason for better reporting and run=False if you don't even want to execute the test function. If only specific exception(s) are expected, you can list them in raises, and if the test fails in other ways, it will be reported as a true failure. See https://docs.pytest.org/en/latest/skipping.html
|
||||
|
||||
@pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see http://pytest.org/latest/parametrize.html for more info and examples.
|
||||
@pytest.mark.parametrize(argnames, argvalues): call a test function multiple times passing in different arguments in turn. argvalues generally needs to be a list of values if argnames specifies only one name or a list of tuples of values if argnames specifies multiple names. Example: @parametrize('arg1', [1,2]) would lead to two calls of the decorated test function, one with arg1=1 and another with arg1=2.see https://docs.pytest.org/en/latest/parametrize.html for more info and examples.
|
||||
|
||||
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures
|
||||
@pytest.mark.usefixtures(fixturename1, fixturename2, ...): mark tests as needing all of the specified fixtures. see https://docs.pytest.org/en/latest/fixture.html#usefixtures
|
||||
|
||||
@pytest.mark.tryfirst: mark a hook implementation function such that the plugin machinery will try to call it first/as early as possible.
|
||||
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
module containing a parametrized tests testing cross-python
|
||||
serialization via the pickle module.
|
||||
"""
|
||||
import textwrap
|
||||
|
||||
import py
|
||||
|
||||
import pytest
|
||||
import _pytest._code
|
||||
|
||||
pythonlist = ["python2.7", "python3.4", "python3.5"]
|
||||
|
||||
@@ -21,46 +23,47 @@ def python2(request, python1):
|
||||
|
||||
|
||||
class Python(object):
|
||||
|
||||
def __init__(self, version, picklefile):
|
||||
self.pythonpath = py.path.local.sysfind(version)
|
||||
if not self.pythonpath:
|
||||
pytest.skip("%r not found" % (version,))
|
||||
pytest.skip("{!r} not found".format(version))
|
||||
self.picklefile = picklefile
|
||||
|
||||
def dumps(self, obj):
|
||||
dumpfile = self.picklefile.dirpath("dump.py")
|
||||
dumpfile.write(
|
||||
_pytest._code.Source(
|
||||
"""
|
||||
import pickle
|
||||
f = open(%r, 'wb')
|
||||
s = pickle.dump(%r, f, protocol=2)
|
||||
f.close()
|
||||
"""
|
||||
% (str(self.picklefile), obj)
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
import pickle
|
||||
f = open({!r}, 'wb')
|
||||
s = pickle.dump({!r}, f, protocol=2)
|
||||
f.close()
|
||||
""".format(
|
||||
str(self.picklefile), obj
|
||||
)
|
||||
)
|
||||
)
|
||||
py.process.cmdexec("%s %s" % (self.pythonpath, dumpfile))
|
||||
py.process.cmdexec("{} {}".format(self.pythonpath, dumpfile))
|
||||
|
||||
def load_and_is_true(self, expression):
|
||||
loadfile = self.picklefile.dirpath("load.py")
|
||||
loadfile.write(
|
||||
_pytest._code.Source(
|
||||
"""
|
||||
import pickle
|
||||
f = open(%r, 'rb')
|
||||
obj = pickle.load(f)
|
||||
f.close()
|
||||
res = eval(%r)
|
||||
if not res:
|
||||
raise SystemExit(1)
|
||||
"""
|
||||
% (str(self.picklefile), expression)
|
||||
textwrap.dedent(
|
||||
"""\
|
||||
import pickle
|
||||
f = open({!r}, 'rb')
|
||||
obj = pickle.load(f)
|
||||
f.close()
|
||||
res = eval({!r})
|
||||
if not res:
|
||||
raise SystemExit(1)
|
||||
""".format(
|
||||
str(self.picklefile), expression
|
||||
)
|
||||
)
|
||||
)
|
||||
print(loadfile)
|
||||
py.process.cmdexec("%s %s" % (self.pythonpath, loadfile))
|
||||
py.process.cmdexec("{} {}".format(self.pythonpath, loadfile))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("obj", [42, {}, {1: 3}])
|
||||
|
||||
@@ -59,7 +59,7 @@ consulted when reporting in ``verbose`` mode::
|
||||
|
||||
nonpython $ pytest -v
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
|
||||
collecting ... collected 2 items
|
||||
@@ -84,8 +84,9 @@ interesting to just look at the collection tree::
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
|
||||
rootdir: $REGENDOC_TMPDIR/nonpython, inifile:
|
||||
collected 2 items
|
||||
<YamlFile 'test_simple.yml'>
|
||||
<YamlItem 'hello'>
|
||||
<YamlItem 'ok'>
|
||||
<Package '$REGENDOC_TMPDIR/nonpython'>
|
||||
<YamlFile 'test_simple.yml'>
|
||||
<YamlItem 'hello'>
|
||||
<YamlItem 'ok'>
|
||||
|
||||
======================= no tests ran in 0.12 seconds =======================
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# content of conftest.py
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@@ -9,7 +8,6 @@ def pytest_collect_file(parent, path):
|
||||
|
||||
|
||||
class YamlFile(pytest.File):
|
||||
|
||||
def collect(self):
|
||||
import yaml # we need a yaml parser, e.g. PyYAML
|
||||
|
||||
@@ -19,7 +17,6 @@ class YamlFile(pytest.File):
|
||||
|
||||
|
||||
class YamlItem(pytest.Item):
|
||||
|
||||
def __init__(self, name, parent, spec):
|
||||
super(YamlItem, self).__init__(name, parent)
|
||||
self.spec = spec
|
||||
|
||||
@@ -411,8 +411,10 @@ is to be run with different sets of arguments for its three arguments:
|
||||
Running it results in some skips if we don't have all the python interpreters installed and otherwise runs all combinations (5 interpreters times 5 interpreters times 3 objects to serialize/deserialize)::
|
||||
|
||||
. $ pytest -rs -q multipython.py
|
||||
........................... [100%]
|
||||
27 passed in 0.12 seconds
|
||||
...sss...sssssssss...sss... [100%]
|
||||
========================= short test summary info ==========================
|
||||
SKIP [15] $REGENDOC_TMPDIR/CWD/multipython.py:30: 'python3.4' not found
|
||||
12 passed, 15 skipped in 0.12 seconds
|
||||
|
||||
Indirect parametrization of optional implementations/imports
|
||||
--------------------------------------------------------------------
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
py3 = sys.version_info[0] >= 3
|
||||
|
||||
|
||||
class DummyCollector(pytest.collect.File):
|
||||
|
||||
def collect(self):
|
||||
return []
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
def test_exception_syntax():
|
||||
try:
|
||||
0/0
|
||||
0 / 0
|
||||
except ZeroDivisionError, e:
|
||||
pass
|
||||
assert e
|
||||
|
||||
@@ -2,4 +2,4 @@ def test_exception_syntax():
|
||||
try:
|
||||
0 / 0
|
||||
except ZeroDivisionError as e:
|
||||
pass
|
||||
assert e
|
||||
|
||||
@@ -7,7 +7,6 @@ def test_function():
|
||||
|
||||
|
||||
class TestClass(object):
|
||||
|
||||
def test_method(self):
|
||||
pass
|
||||
|
||||
|
||||
@@ -100,19 +100,21 @@ Changing naming conventions
|
||||
|
||||
You can configure different naming conventions by setting
|
||||
the :confval:`python_files`, :confval:`python_classes` and
|
||||
:confval:`python_functions` configuration options. Example::
|
||||
:confval:`python_functions` configuration options.
|
||||
Here is an example::
|
||||
|
||||
# content of pytest.ini
|
||||
# Example 1: have pytest look for "check" instead of "test"
|
||||
# can also be defined in tox.ini or setup.cfg file, although the section
|
||||
# name in setup.cfg files should be "tool:pytest"
|
||||
[pytest]
|
||||
python_files=check_*.py
|
||||
python_classes=Check
|
||||
python_functions=*_check
|
||||
python_files = check_*.py
|
||||
python_classes = Check
|
||||
python_functions = *_check
|
||||
|
||||
This would make ``pytest`` look for tests in files that match the ``check_*
|
||||
.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
|
||||
that match ``*_check``. For example, if we have::
|
||||
that match ``*_check``. For example, if we have::
|
||||
|
||||
# content of check_myapp.py
|
||||
class CheckMyApp(object):
|
||||
@@ -121,7 +123,7 @@ that match ``*_check``. For example, if we have::
|
||||
def complex_check(self):
|
||||
pass
|
||||
|
||||
then the test collection looks like this::
|
||||
The test collection would look like this::
|
||||
|
||||
$ pytest --collect-only
|
||||
=========================== test session starts ============================
|
||||
@@ -136,11 +138,19 @@ then the test collection looks like this::
|
||||
|
||||
======================= no tests ran in 0.12 seconds =======================
|
||||
|
||||
You can check for multiple glob patterns by adding a space between the patterns::
|
||||
|
||||
# Example 2: have pytest look for files with "test" and "example"
|
||||
# content of pytest.ini, tox.ini, or setup.cfg file (replace "pytest"
|
||||
# with "tool:pytest" for setup.cfg)
|
||||
[pytest]
|
||||
python_files = test_*.py example_*.py
|
||||
|
||||
.. note::
|
||||
|
||||
the ``python_functions`` and ``python_classes`` options has no effect
|
||||
for ``unittest.TestCase`` test discovery because pytest delegates
|
||||
detection of test case methods to unittest code.
|
||||
discovery of test case methods to unittest code.
|
||||
|
||||
Interpreting cmdline arguments as Python packages
|
||||
-----------------------------------------------------
|
||||
|
||||
@@ -26,13 +26,12 @@ get on the terminal - we are working on that)::
|
||||
> assert param1 * 2 < param2
|
||||
E assert (3 * 2) < 6
|
||||
|
||||
failure_demo.py:19: AssertionError
|
||||
failure_demo.py:20: AssertionError
|
||||
_________________________ TestFailing.test_simple __________________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0xdeadbeef>
|
||||
|
||||
def test_simple(self):
|
||||
|
||||
def f():
|
||||
return 42
|
||||
|
||||
@@ -44,7 +43,7 @@ get on the terminal - we are working on that)::
|
||||
E + where 42 = <function TestFailing.test_simple.<locals>.f at 0xdeadbeef>()
|
||||
E + and 43 = <function TestFailing.test_simple.<locals>.g at 0xdeadbeef>()
|
||||
|
||||
failure_demo.py:37: AssertionError
|
||||
failure_demo.py:36: AssertionError
|
||||
____________________ TestFailing.test_simple_multiline _____________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0xdeadbeef>
|
||||
@@ -52,7 +51,7 @@ get on the terminal - we are working on that)::
|
||||
def test_simple_multiline(self):
|
||||
> otherfunc_multi(42, 6 * 9)
|
||||
|
||||
failure_demo.py:40:
|
||||
failure_demo.py:39:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
a = 42, b = 54
|
||||
@@ -61,13 +60,12 @@ get on the terminal - we are working on that)::
|
||||
> assert a == b
|
||||
E assert 42 == 54
|
||||
|
||||
failure_demo.py:15: AssertionError
|
||||
failure_demo.py:16: AssertionError
|
||||
___________________________ TestFailing.test_not ___________________________
|
||||
|
||||
self = <failure_demo.TestFailing object at 0xdeadbeef>
|
||||
|
||||
def test_not(self):
|
||||
|
||||
def f():
|
||||
return 42
|
||||
|
||||
@@ -75,7 +73,7 @@ get on the terminal - we are working on that)::
|
||||
E assert not 42
|
||||
E + where 42 = <function TestFailing.test_not.<locals>.f at 0xdeadbeef>()
|
||||
|
||||
failure_demo.py:47: AssertionError
|
||||
failure_demo.py:45: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_text _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -86,7 +84,7 @@ get on the terminal - we are working on that)::
|
||||
E - spam
|
||||
E + eggs
|
||||
|
||||
failure_demo.py:53: AssertionError
|
||||
failure_demo.py:50: AssertionError
|
||||
_____________ TestSpecialisedExplanations.test_eq_similar_text _____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -99,7 +97,7 @@ get on the terminal - we are working on that)::
|
||||
E + foo 2 bar
|
||||
E ? ^
|
||||
|
||||
failure_demo.py:56: AssertionError
|
||||
failure_demo.py:53: AssertionError
|
||||
____________ TestSpecialisedExplanations.test_eq_multiline_text ____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -112,7 +110,7 @@ get on the terminal - we are working on that)::
|
||||
E + eggs
|
||||
E bar
|
||||
|
||||
failure_demo.py:59: AssertionError
|
||||
failure_demo.py:56: AssertionError
|
||||
______________ TestSpecialisedExplanations.test_eq_long_text _______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -129,7 +127,7 @@ get on the terminal - we are working on that)::
|
||||
E + 1111111111b222222222
|
||||
E ? ^
|
||||
|
||||
failure_demo.py:64: AssertionError
|
||||
failure_demo.py:61: AssertionError
|
||||
_________ TestSpecialisedExplanations.test_eq_long_text_multiline __________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -149,7 +147,7 @@ get on the terminal - we are working on that)::
|
||||
E
|
||||
E ...Full output truncated (7 lines hidden), use '-vv' to show
|
||||
|
||||
failure_demo.py:69: AssertionError
|
||||
failure_demo.py:66: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_list _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -160,7 +158,7 @@ get on the terminal - we are working on that)::
|
||||
E At index 2 diff: 2 != 3
|
||||
E Use -v to get the full diff
|
||||
|
||||
failure_demo.py:72: AssertionError
|
||||
failure_demo.py:69: AssertionError
|
||||
______________ TestSpecialisedExplanations.test_eq_list_long _______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -173,7 +171,7 @@ get on the terminal - we are working on that)::
|
||||
E At index 100 diff: 1 != 2
|
||||
E Use -v to get the full diff
|
||||
|
||||
failure_demo.py:77: AssertionError
|
||||
failure_demo.py:74: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_dict _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -191,7 +189,7 @@ get on the terminal - we are working on that)::
|
||||
E
|
||||
E ...Full output truncated (2 lines hidden), use '-vv' to show
|
||||
|
||||
failure_demo.py:80: AssertionError
|
||||
failure_demo.py:77: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_eq_set __________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -209,7 +207,7 @@ get on the terminal - we are working on that)::
|
||||
E
|
||||
E ...Full output truncated (2 lines hidden), use '-vv' to show
|
||||
|
||||
failure_demo.py:83: AssertionError
|
||||
failure_demo.py:80: AssertionError
|
||||
_____________ TestSpecialisedExplanations.test_eq_longer_list ______________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -220,7 +218,7 @@ get on the terminal - we are working on that)::
|
||||
E Right contains more items, first extra item: 3
|
||||
E Use -v to get the full diff
|
||||
|
||||
failure_demo.py:86: AssertionError
|
||||
failure_demo.py:83: AssertionError
|
||||
_________________ TestSpecialisedExplanations.test_in_list _________________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -229,7 +227,7 @@ get on the terminal - we are working on that)::
|
||||
> assert 1 in [0, 2, 3, 4, 5]
|
||||
E assert 1 in [0, 2, 3, 4, 5]
|
||||
|
||||
failure_demo.py:89: AssertionError
|
||||
failure_demo.py:86: AssertionError
|
||||
__________ TestSpecialisedExplanations.test_not_in_text_multiline __________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -248,7 +246,7 @@ get on the terminal - we are working on that)::
|
||||
E
|
||||
E ...Full output truncated (2 lines hidden), use '-vv' to show
|
||||
|
||||
failure_demo.py:93: AssertionError
|
||||
failure_demo.py:90: AssertionError
|
||||
___________ TestSpecialisedExplanations.test_not_in_text_single ____________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -261,7 +259,7 @@ get on the terminal - we are working on that)::
|
||||
E single foo line
|
||||
E ? +++
|
||||
|
||||
failure_demo.py:97: AssertionError
|
||||
failure_demo.py:94: AssertionError
|
||||
_________ TestSpecialisedExplanations.test_not_in_text_single_long _________
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -274,7 +272,7 @@ get on the terminal - we are working on that)::
|
||||
E head head foo tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail
|
||||
E ? +++
|
||||
|
||||
failure_demo.py:101: AssertionError
|
||||
failure_demo.py:98: AssertionError
|
||||
______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______
|
||||
|
||||
self = <failure_demo.TestSpecialisedExplanations object at 0xdeadbeef>
|
||||
@@ -287,11 +285,10 @@ get on the terminal - we are working on that)::
|
||||
E head head fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffftail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail tail
|
||||
E ? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
failure_demo.py:105: AssertionError
|
||||
failure_demo.py:102: AssertionError
|
||||
______________________________ test_attribute ______________________________
|
||||
|
||||
def test_attribute():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -300,11 +297,10 @@ get on the terminal - we are working on that)::
|
||||
E assert 1 == 2
|
||||
E + where 1 = <failure_demo.test_attribute.<locals>.Foo object at 0xdeadbeef>.b
|
||||
|
||||
failure_demo.py:114: AssertionError
|
||||
failure_demo.py:110: AssertionError
|
||||
_________________________ test_attribute_instance __________________________
|
||||
|
||||
def test_attribute_instance():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -313,13 +309,11 @@ get on the terminal - we are working on that)::
|
||||
E + where 1 = <failure_demo.test_attribute_instance.<locals>.Foo object at 0xdeadbeef>.b
|
||||
E + where <failure_demo.test_attribute_instance.<locals>.Foo object at 0xdeadbeef> = <class 'failure_demo.test_attribute_instance.<locals>.Foo'>()
|
||||
|
||||
failure_demo.py:122: AssertionError
|
||||
failure_demo.py:117: AssertionError
|
||||
__________________________ test_attribute_failure __________________________
|
||||
|
||||
def test_attribute_failure():
|
||||
|
||||
class Foo(object):
|
||||
|
||||
def _get_b(self):
|
||||
raise Exception("Failed to get attrib")
|
||||
|
||||
@@ -328,7 +322,7 @@ get on the terminal - we are working on that)::
|
||||
i = Foo()
|
||||
> assert i.b == 2
|
||||
|
||||
failure_demo.py:135:
|
||||
failure_demo.py:128:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
self = <failure_demo.test_attribute_failure.<locals>.Foo object at 0xdeadbeef>
|
||||
@@ -337,11 +331,10 @@ get on the terminal - we are working on that)::
|
||||
> raise Exception("Failed to get attrib")
|
||||
E Exception: Failed to get attrib
|
||||
|
||||
failure_demo.py:130: Exception
|
||||
failure_demo.py:123: Exception
|
||||
_________________________ test_attribute_multiple __________________________
|
||||
|
||||
def test_attribute_multiple():
|
||||
|
||||
class Foo(object):
|
||||
b = 1
|
||||
|
||||
@@ -355,7 +348,7 @@ get on the terminal - we are working on that)::
|
||||
E + and 2 = <failure_demo.test_attribute_multiple.<locals>.Bar object at 0xdeadbeef>.b
|
||||
E + where <failure_demo.test_attribute_multiple.<locals>.Bar object at 0xdeadbeef> = <class 'failure_demo.test_attribute_multiple.<locals>.Bar'>()
|
||||
|
||||
failure_demo.py:146: AssertionError
|
||||
failure_demo.py:138: AssertionError
|
||||
__________________________ TestRaises.test_raises __________________________
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
@@ -364,13 +357,13 @@ get on the terminal - we are working on that)::
|
||||
s = "qwe" # NOQA
|
||||
> raises(TypeError, "int(s)")
|
||||
|
||||
failure_demo.py:157:
|
||||
failure_demo.py:148:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
> int(s)
|
||||
E ValueError: invalid literal for int() with base 10: 'qwe'
|
||||
|
||||
<0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:634>:1: ValueError
|
||||
<0-codegen $PYTHON_PREFIX/lib/python3.6/site-packages/_pytest/python_api.py:682>:1: ValueError
|
||||
______________________ TestRaises.test_raises_doesnt _______________________
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
@@ -379,7 +372,7 @@ get on the terminal - we are working on that)::
|
||||
> raises(IOError, "int('3')")
|
||||
E Failed: DID NOT RAISE <class 'OSError'>
|
||||
|
||||
failure_demo.py:160: Failed
|
||||
failure_demo.py:151: Failed
|
||||
__________________________ TestRaises.test_raise ___________________________
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
@@ -388,7 +381,7 @@ get on the terminal - we are working on that)::
|
||||
> raise ValueError("demo error")
|
||||
E ValueError: demo error
|
||||
|
||||
failure_demo.py:163: ValueError
|
||||
failure_demo.py:154: ValueError
|
||||
________________________ TestRaises.test_tupleerror ________________________
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
@@ -397,7 +390,7 @@ get on the terminal - we are working on that)::
|
||||
> a, b = [1] # NOQA
|
||||
E ValueError: not enough values to unpack (expected 2, got 1)
|
||||
|
||||
failure_demo.py:166: ValueError
|
||||
failure_demo.py:157: ValueError
|
||||
______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______
|
||||
|
||||
self = <failure_demo.TestRaises object at 0xdeadbeef>
|
||||
@@ -408,7 +401,7 @@ get on the terminal - we are working on that)::
|
||||
> a, b = items.pop()
|
||||
E TypeError: 'int' object is not iterable
|
||||
|
||||
failure_demo.py:171: TypeError
|
||||
failure_demo.py:162: TypeError
|
||||
--------------------------- Captured stdout call ---------------------------
|
||||
items is [1, 2, 3]
|
||||
________________________ TestRaises.test_some_error ________________________
|
||||
@@ -419,7 +412,7 @@ get on the terminal - we are working on that)::
|
||||
> if namenotexi: # NOQA
|
||||
E NameError: name 'namenotexi' is not defined
|
||||
|
||||
failure_demo.py:174: NameError
|
||||
failure_demo.py:165: NameError
|
||||
____________________ test_dynamic_compile_shows_nicely _____________________
|
||||
|
||||
def test_dynamic_compile_shows_nicely():
|
||||
@@ -430,24 +423,23 @@ get on the terminal - we are working on that)::
|
||||
name = "abc-123"
|
||||
module = imp.new_module(name)
|
||||
code = _pytest._code.compile(src, name, "exec")
|
||||
py.builtin.exec_(code, module.__dict__)
|
||||
six.exec_(code, module.__dict__)
|
||||
sys.modules[name] = module
|
||||
> module.foo()
|
||||
|
||||
failure_demo.py:192:
|
||||
failure_demo.py:183:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
def foo():
|
||||
> assert 1 == 0
|
||||
E AssertionError
|
||||
|
||||
<2-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:189>:2: AssertionError
|
||||
<2-codegen 'abc-123' $REGENDOC_TMPDIR/assertion/failure_demo.py:180>:2: AssertionError
|
||||
____________________ TestMoreErrors.test_complex_error _____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
|
||||
def test_complex_error(self):
|
||||
|
||||
def f():
|
||||
return 44
|
||||
|
||||
@@ -456,9 +448,9 @@ get on the terminal - we are working on that)::
|
||||
|
||||
> somefunc(f(), g())
|
||||
|
||||
failure_demo.py:205:
|
||||
failure_demo.py:194:
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
failure_demo.py:11: in somefunc
|
||||
failure_demo.py:12: in somefunc
|
||||
otherfunc(x, y)
|
||||
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
|
||||
@@ -468,7 +460,7 @@ get on the terminal - we are working on that)::
|
||||
> assert a == b
|
||||
E assert 44 == 43
|
||||
|
||||
failure_demo.py:7: AssertionError
|
||||
failure_demo.py:8: AssertionError
|
||||
___________________ TestMoreErrors.test_z1_unpack_error ____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -478,7 +470,7 @@ get on the terminal - we are working on that)::
|
||||
> a, b = items
|
||||
E ValueError: not enough values to unpack (expected 2, got 0)
|
||||
|
||||
failure_demo.py:209: ValueError
|
||||
failure_demo.py:198: ValueError
|
||||
____________________ TestMoreErrors.test_z2_type_error _____________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -488,7 +480,7 @@ get on the terminal - we are working on that)::
|
||||
> a, b = items
|
||||
E TypeError: 'int' object is not iterable
|
||||
|
||||
failure_demo.py:213: TypeError
|
||||
failure_demo.py:202: TypeError
|
||||
______________________ TestMoreErrors.test_startswith ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -501,13 +493,12 @@ get on the terminal - we are working on that)::
|
||||
E + where False = <built-in method startswith of str object at 0xdeadbeef>('456')
|
||||
E + where <built-in method startswith of str object at 0xdeadbeef> = '123'.startswith
|
||||
|
||||
failure_demo.py:218: AssertionError
|
||||
failure_demo.py:207: AssertionError
|
||||
__________________ TestMoreErrors.test_startswith_nested ___________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
|
||||
def test_startswith_nested(self):
|
||||
|
||||
def f():
|
||||
return "123"
|
||||
|
||||
@@ -521,7 +512,7 @@ get on the terminal - we are working on that)::
|
||||
E + where '123' = <function TestMoreErrors.test_startswith_nested.<locals>.f at 0xdeadbeef>()
|
||||
E + and '456' = <function TestMoreErrors.test_startswith_nested.<locals>.g at 0xdeadbeef>()
|
||||
|
||||
failure_demo.py:228: AssertionError
|
||||
failure_demo.py:216: AssertionError
|
||||
_____________________ TestMoreErrors.test_global_func ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -532,7 +523,7 @@ get on the terminal - we are working on that)::
|
||||
E + where False = isinstance(43, float)
|
||||
E + where 43 = globf(42)
|
||||
|
||||
failure_demo.py:231: AssertionError
|
||||
failure_demo.py:219: AssertionError
|
||||
_______________________ TestMoreErrors.test_instance _______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -543,7 +534,7 @@ get on the terminal - we are working on that)::
|
||||
E assert 42 != 42
|
||||
E + where 42 = <failure_demo.TestMoreErrors object at 0xdeadbeef>.x
|
||||
|
||||
failure_demo.py:235: AssertionError
|
||||
failure_demo.py:223: AssertionError
|
||||
_______________________ TestMoreErrors.test_compare ________________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -553,7 +544,7 @@ get on the terminal - we are working on that)::
|
||||
E assert 11 < 5
|
||||
E + where 11 = globf(10)
|
||||
|
||||
failure_demo.py:238: AssertionError
|
||||
failure_demo.py:226: AssertionError
|
||||
_____________________ TestMoreErrors.test_try_finally ______________________
|
||||
|
||||
self = <failure_demo.TestMoreErrors object at 0xdeadbeef>
|
||||
@@ -564,13 +555,12 @@ get on the terminal - we are working on that)::
|
||||
> assert x == 0
|
||||
E assert 1 == 0
|
||||
|
||||
failure_demo.py:243: AssertionError
|
||||
failure_demo.py:231: AssertionError
|
||||
___________________ TestCustomAssertMsg.test_single_line ___________________
|
||||
|
||||
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef>
|
||||
|
||||
def test_single_line(self):
|
||||
|
||||
class A(object):
|
||||
a = 1
|
||||
|
||||
@@ -580,33 +570,31 @@ get on the terminal - we are working on that)::
|
||||
E assert 1 == 2
|
||||
E + where 1 = <class 'failure_demo.TestCustomAssertMsg.test_single_line.<locals>.A'>.a
|
||||
|
||||
failure_demo.py:256: AssertionError
|
||||
failure_demo.py:242: AssertionError
|
||||
____________________ TestCustomAssertMsg.test_multiline ____________________
|
||||
|
||||
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef>
|
||||
|
||||
def test_multiline(self):
|
||||
|
||||
class A(object):
|
||||
a = 1
|
||||
|
||||
b = 2
|
||||
> assert (
|
||||
A.a == b
|
||||
), "A.a appears not to be b\n" "or does not appear to be b\none of those"
|
||||
), "A.a appears not to be b\nor does not appear to be b\none of those"
|
||||
E AssertionError: A.a appears not to be b
|
||||
E or does not appear to be b
|
||||
E one of those
|
||||
E assert 1 == 2
|
||||
E + where 1 = <class 'failure_demo.TestCustomAssertMsg.test_multiline.<locals>.A'>.a
|
||||
|
||||
failure_demo.py:264: AssertionError
|
||||
failure_demo.py:249: AssertionError
|
||||
___________________ TestCustomAssertMsg.test_custom_repr ___________________
|
||||
|
||||
self = <failure_demo.TestCustomAssertMsg object at 0xdeadbeef>
|
||||
|
||||
def test_custom_repr(self):
|
||||
|
||||
class JSON(object):
|
||||
a = 1
|
||||
|
||||
@@ -623,11 +611,12 @@ get on the terminal - we are working on that)::
|
||||
E assert 1 == 2
|
||||
E + where 1 = This is JSON\n{\n 'foo': 'bar'\n}.a
|
||||
|
||||
failure_demo.py:278: AssertionError
|
||||
failure_demo.py:262: AssertionError
|
||||
============================= warnings summary =============================
|
||||
None
|
||||
Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0.
|
||||
failure_demo.py:25
|
||||
$REGENDOC_TMPDIR/assertion/failure_demo.py:25: RemovedInPytest4Warning: Metafunc.addcall is deprecated and scheduled to be removed in pytest 4.0.
|
||||
Please use Metafunc.parametrize instead.
|
||||
metafunc.addcall(funcargs=dict(param1=3, param2=6))
|
||||
|
||||
-- Docs: http://doc.pytest.org/en/latest/warnings.html
|
||||
-- Docs: https://docs.pytest.org/en/latest/warnings.html
|
||||
================== 42 failed, 1 warnings in 0.12 seconds ===================
|
||||
|
||||
@@ -357,7 +357,7 @@ which will add info only when run with "--v"::
|
||||
|
||||
$ pytest -v
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
info1: did you know that ...
|
||||
did you?
|
||||
@@ -574,7 +574,7 @@ We can run this::
|
||||
file $REGENDOC_TMPDIR/b/test_error.py, line 1
|
||||
def test_root(db): # no db here, will error out
|
||||
E fixture 'db' not found
|
||||
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory
|
||||
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, pytestconfig, record_property, record_xml_attribute, record_xml_property, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
|
||||
> use 'pytest --fixtures [testpath]' for help on them.
|
||||
|
||||
$REGENDOC_TMPDIR/b/test_error.py:1
|
||||
@@ -852,6 +852,8 @@ In that order.
|
||||
can be changed between releases (even bug fixes) so it shouldn't be relied on for scripting
|
||||
or automation.
|
||||
|
||||
.. _freezing-pytest:
|
||||
|
||||
Freezing pytest
|
||||
---------------
|
||||
|
||||
|
||||
@@ -55,18 +55,18 @@ using it::
|
||||
import pytest
|
||||
|
||||
@pytest.fixture
|
||||
def smtp():
|
||||
def smtp_connection():
|
||||
import smtplib
|
||||
return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
assert 0 # for demo purposes
|
||||
|
||||
Here, the ``test_ehlo`` needs the ``smtp`` fixture value. pytest
|
||||
Here, the ``test_ehlo`` needs the ``smtp_connection`` fixture value. pytest
|
||||
will discover and call the :py:func:`@pytest.fixture <_pytest.python.fixture>`
|
||||
marked ``smtp`` fixture function. Running the test looks like this::
|
||||
marked ``smtp_connection`` fixture function. Running the test looks like this::
|
||||
|
||||
$ pytest test_smtpsimple.py
|
||||
=========================== test session starts ============================
|
||||
@@ -79,10 +79,10 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
================================= FAILURES =================================
|
||||
________________________________ test_ehlo _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
> assert 0 # for demo purposes
|
||||
E assert 0
|
||||
@@ -91,18 +91,18 @@ marked ``smtp`` fixture function. Running the test looks like this::
|
||||
========================= 1 failed in 0.12 seconds =========================
|
||||
|
||||
In the failure traceback we see that the test function was called with a
|
||||
``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture
|
||||
``smtp_connection`` argument, the ``smtplib.SMTP()`` instance created by the fixture
|
||||
function. The test function fails on our deliberate ``assert 0``. Here is
|
||||
the exact protocol used by ``pytest`` to call the test function this way:
|
||||
|
||||
1. pytest :ref:`finds <test discovery>` the ``test_ehlo`` because
|
||||
of the ``test_`` prefix. The test function needs a function argument
|
||||
named ``smtp``. A matching fixture function is discovered by
|
||||
looking for a fixture-marked function named ``smtp``.
|
||||
named ``smtp_connection``. A matching fixture function is discovered by
|
||||
looking for a fixture-marked function named ``smtp_connection``.
|
||||
|
||||
2. ``smtp()`` is called to create an instance.
|
||||
2. ``smtp_connection()`` is called to create an instance.
|
||||
|
||||
3. ``test_ehlo(<SMTP instance>)`` is called and fails in the last
|
||||
3. ``test_ehlo(<smtp_connection instance>)`` is called and fails in the last
|
||||
line of the test function.
|
||||
|
||||
Note that if you misspell a function argument or want
|
||||
@@ -154,7 +154,7 @@ This makes use of the automatic caching mechanisms of pytest.
|
||||
Another good approach is by adding the data files in the ``tests`` folder.
|
||||
There are also community plugins available to help managing this aspect of
|
||||
testing, e.g. `pytest-datadir <https://github.com/gabrielcnr/pytest-datadir>`__
|
||||
and `pytest-datafiles <https://pypi.python.org/pypi/pytest-datafiles>`__.
|
||||
and `pytest-datafiles <https://pypi.org/project/pytest-datafiles/>`__.
|
||||
|
||||
.. _smtpshared:
|
||||
|
||||
@@ -165,12 +165,13 @@ Scope: sharing a fixture instance across tests in a class, module or session
|
||||
|
||||
Fixtures requiring network access depend on connectivity and are
|
||||
usually time-expensive to create. Extending the previous example, we
|
||||
can add a ``scope='module'`` parameter to the
|
||||
can add a ``scope="module"`` parameter to the
|
||||
:py:func:`@pytest.fixture <_pytest.python.fixture>` invocation
|
||||
to cause the decorated ``smtp`` fixture function to only be invoked once
|
||||
per test *module* (the default is to invoke once per test *function*).
|
||||
to cause the decorated ``smtp_connection`` fixture function to only be invoked
|
||||
once per test *module* (the default is to invoke once per test *function*).
|
||||
Multiple test functions in a test module will thus
|
||||
each receive the same ``smtp`` fixture instance, thus saving time.
|
||||
each receive the same ``smtp_connection`` fixture instance, thus saving time.
|
||||
Possible values for ``scope`` are: ``function``, ``class``, ``module``, ``package`` or ``session``.
|
||||
|
||||
The next example puts the fixture function into a separate ``conftest.py`` file
|
||||
so that tests from multiple test modules in the directory can
|
||||
@@ -181,23 +182,24 @@ access the fixture function::
|
||||
import smtplib
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def smtp():
|
||||
def smtp_connection():
|
||||
return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
|
||||
The name of the fixture again is ``smtp`` and you can access its result by
|
||||
listing the name ``smtp`` as an input parameter in any test or fixture
|
||||
function (in or below the directory where ``conftest.py`` is located)::
|
||||
The name of the fixture again is ``smtp_connection`` and you can access its
|
||||
result by listing the name ``smtp_connection`` as an input parameter in any
|
||||
test or fixture function (in or below the directory where ``conftest.py`` is
|
||||
located)::
|
||||
|
||||
# content of test_module.py
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
assert b"smtp.gmail.com" in msg
|
||||
assert 0 # for demo purposes
|
||||
|
||||
def test_noop(smtp):
|
||||
response, msg = smtp.noop()
|
||||
def test_noop(smtp_connection):
|
||||
response, msg = smtp_connection.noop()
|
||||
assert response == 250
|
||||
assert 0 # for demo purposes
|
||||
|
||||
@@ -215,10 +217,10 @@ inspect what is going on and can now run the tests::
|
||||
================================= FAILURES =================================
|
||||
________________________________ test_ehlo _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
assert b"smtp.gmail.com" in msg
|
||||
> assert 0 # for demo purposes
|
||||
@@ -227,10 +229,10 @@ inspect what is going on and can now run the tests::
|
||||
test_module.py:6: AssertionError
|
||||
________________________________ test_noop _________________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_noop(smtp):
|
||||
response, msg = smtp.noop()
|
||||
def test_noop(smtp_connection):
|
||||
response, msg = smtp_connection.noop()
|
||||
assert response == 250
|
||||
> assert 0 # for demo purposes
|
||||
E assert 0
|
||||
@@ -239,24 +241,45 @@ inspect what is going on and can now run the tests::
|
||||
========================= 2 failed in 0.12 seconds =========================
|
||||
|
||||
You see the two ``assert 0`` failing and more importantly you can also see
|
||||
that the same (module-scoped) ``smtp`` object was passed into the two
|
||||
test functions because pytest shows the incoming argument values in the
|
||||
traceback. As a result, the two test functions using ``smtp`` run as
|
||||
quick as a single one because they reuse the same instance.
|
||||
that the same (module-scoped) ``smtp_connection`` object was passed into the
|
||||
two test functions because pytest shows the incoming argument values in the
|
||||
traceback. As a result, the two test functions using ``smtp_connection`` run
|
||||
as quick as a single one because they reuse the same instance.
|
||||
|
||||
If you decide that you rather want to have a session-scoped ``smtp``
|
||||
If you decide that you rather want to have a session-scoped ``smtp_connection``
|
||||
instance, you can simply declare it:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def smtp():
|
||||
def smtp_connection():
|
||||
# the returned fixture value will be shared for
|
||||
# all tests needing it
|
||||
...
|
||||
|
||||
Finally, the ``class`` scope will invoke the fixture once per test *class*.
|
||||
|
||||
.. note::
|
||||
|
||||
Pytest will only cache one instance of a fixture at a time.
|
||||
This means that when using a parametrized fixture, pytest may invoke a fixture more than once in the given scope.
|
||||
|
||||
|
||||
``package`` scope (experimental)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 3.7
|
||||
|
||||
In pytest 3.7 the ``package`` scope has been introduced. Package-scoped fixtures
|
||||
are finalized when the last test of a *package* finishes.
|
||||
|
||||
.. warning::
|
||||
This functionality is considered **experimental** and may be removed in future
|
||||
versions if hidden corner-cases or serious problems with this functionality
|
||||
are discovered after it gets more usage in the wild.
|
||||
|
||||
Use this new feature sparingly and please make sure to report any issues you find.
|
||||
|
||||
|
||||
Higher-scoped fixtures are instantiated first
|
||||
---------------------------------------------
|
||||
@@ -323,11 +346,11 @@ the code after the *yield* statement serves as the teardown code:
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def smtp():
|
||||
smtp = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
yield smtp # provide the fixture value
|
||||
def smtp_connection():
|
||||
smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
yield smtp_connection # provide the fixture value
|
||||
print("teardown smtp")
|
||||
smtp.close()
|
||||
smtp_connection.close()
|
||||
|
||||
The ``print`` and ``smtp.close()`` statements will execute when the last test in
|
||||
the module has finished execution, regardless of the exception status of the
|
||||
@@ -340,7 +363,7 @@ Let's execute it::
|
||||
|
||||
2 failed in 0.12 seconds
|
||||
|
||||
We see that the ``smtp`` instance is finalized after the two
|
||||
We see that the ``smtp_connection`` instance is finalized after the two
|
||||
tests finished execution. Note that if we decorated our fixture
|
||||
function with ``scope='function'`` then fixture setup and cleanup would
|
||||
occur around each single test. In either case the test
|
||||
@@ -358,13 +381,13 @@ Note that we can also seamlessly use the ``yield`` syntax with ``with`` statemen
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def smtp():
|
||||
with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp:
|
||||
yield smtp # provide the fixture value
|
||||
def smtp_connection():
|
||||
with smtplib.SMTP("smtp.gmail.com", 587, timeout=5) as smtp_connection:
|
||||
yield smtp_connection # provide the fixture value
|
||||
|
||||
|
||||
The ``smtp`` connection will be closed after the test finished execution
|
||||
because the ``smtp`` object automatically closes when
|
||||
The ``smtp_connection`` connection will be closed after the test finished
|
||||
execution because the ``smtp_connection`` object automatically closes when
|
||||
the ``with`` statement ends.
|
||||
|
||||
Note that if an exception happens during the *setup* code (before the ``yield`` keyword), the
|
||||
@@ -374,7 +397,7 @@ An alternative option for executing *teardown* code is to
|
||||
make use of the ``addfinalizer`` method of the `request-context`_ object to register
|
||||
finalization functions.
|
||||
|
||||
Here's the ``smtp`` fixture changed to use ``addfinalizer`` for cleanup:
|
||||
Here's the ``smtp_connection`` fixture changed to use ``addfinalizer`` for cleanup:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -384,15 +407,15 @@ Here's the ``smtp`` fixture changed to use ``addfinalizer`` for cleanup:
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def smtp(request):
|
||||
smtp = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
def smtp_connection(request):
|
||||
smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
|
||||
|
||||
def fin():
|
||||
print("teardown smtp")
|
||||
smtp.close()
|
||||
print("teardown smtp_connection")
|
||||
smtp_connection.close()
|
||||
|
||||
request.addfinalizer(fin)
|
||||
return smtp # provide the fixture value
|
||||
return smtp_connection # provide the fixture value
|
||||
|
||||
|
||||
Both ``yield`` and ``addfinalizer`` methods work similarly by calling their code after the test
|
||||
@@ -425,7 +448,7 @@ Fixtures can introspect the requesting test context
|
||||
|
||||
Fixture functions can accept the :py:class:`request <FixtureRequest>` object
|
||||
to introspect the "requesting" test function, class or module context.
|
||||
Further extending the previous ``smtp`` fixture example, let's
|
||||
Further extending the previous ``smtp_connection`` fixture example, let's
|
||||
read an optional server URL from the test module which uses our fixture::
|
||||
|
||||
# content of conftest.py
|
||||
@@ -433,12 +456,12 @@ read an optional server URL from the test module which uses our fixture::
|
||||
import smtplib
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def smtp(request):
|
||||
def smtp_connection(request):
|
||||
server = getattr(request.module, "smtpserver", "smtp.gmail.com")
|
||||
smtp = smtplib.SMTP(server, 587, timeout=5)
|
||||
yield smtp
|
||||
print ("finalizing %s (%s)" % (smtp, server))
|
||||
smtp.close()
|
||||
smtp_connection = smtplib.SMTP(server, 587, timeout=5)
|
||||
yield smtp_connection
|
||||
print ("finalizing %s (%s)" % (smtp_connection, server))
|
||||
smtp_connection.close()
|
||||
|
||||
We use the ``request.module`` attribute to optionally obtain an
|
||||
``smtpserver`` attribute from the test module. If we just execute
|
||||
@@ -456,8 +479,8 @@ server URL in its module namespace::
|
||||
|
||||
smtpserver = "mail.python.org" # will be read by smtp fixture
|
||||
|
||||
def test_showhelo(smtp):
|
||||
assert 0, smtp.helo()
|
||||
def test_showhelo(smtp_connection):
|
||||
assert 0, smtp_connection.helo()
|
||||
|
||||
Running it::
|
||||
|
||||
@@ -466,13 +489,13 @@ Running it::
|
||||
================================= FAILURES =================================
|
||||
______________________________ test_showhelo _______________________________
|
||||
test_anothersmtp.py:5: in test_showhelo
|
||||
assert 0, smtp.helo()
|
||||
assert 0, smtp_connection.helo()
|
||||
E AssertionError: (250, b'mail.python.org')
|
||||
E assert 0
|
||||
------------------------- Captured stdout teardown -------------------------
|
||||
finalizing <smtplib.SMTP object at 0xdeadbeef> (mail.python.org)
|
||||
|
||||
voila! The ``smtp`` fixture function picked up our mail server name
|
||||
voila! The ``smtp_connection`` fixture function picked up our mail server name
|
||||
from the module namespace.
|
||||
|
||||
.. _`fixture-factory`:
|
||||
@@ -535,13 +558,13 @@ Parametrizing fixtures
|
||||
|
||||
Fixture functions can be parametrized in which case they will be called
|
||||
multiple times, each time executing the set of dependent tests, i. e. the
|
||||
tests that depend on this fixture. Test functions do usually not need
|
||||
tests that depend on this fixture. Test functions usually do not need
|
||||
to be aware of their re-running. Fixture parametrization helps to
|
||||
write exhaustive functional tests for components which themselves can be
|
||||
configured in multiple ways.
|
||||
|
||||
Extending the previous example, we can flag the fixture to create two
|
||||
``smtp`` fixture instances which will cause all tests using the fixture
|
||||
``smtp_connection`` fixture instances which will cause all tests using the fixture
|
||||
to run twice. The fixture function gets access to each parameter
|
||||
through the special :py:class:`request <FixtureRequest>` object::
|
||||
|
||||
@@ -551,11 +574,11 @@ through the special :py:class:`request <FixtureRequest>` object::
|
||||
|
||||
@pytest.fixture(scope="module",
|
||||
params=["smtp.gmail.com", "mail.python.org"])
|
||||
def smtp(request):
|
||||
smtp = smtplib.SMTP(request.param, 587, timeout=5)
|
||||
yield smtp
|
||||
print ("finalizing %s" % smtp)
|
||||
smtp.close()
|
||||
def smtp_connection(request):
|
||||
smtp_connection = smtplib.SMTP(request.param, 587, timeout=5)
|
||||
yield smtp_connection
|
||||
print("finalizing %s" % smtp_connection)
|
||||
smtp_connection.close()
|
||||
|
||||
The main change is the declaration of ``params`` with
|
||||
:py:func:`@pytest.fixture <_pytest.python.fixture>`, a list of values
|
||||
@@ -568,10 +591,10 @@ So let's just do another run::
|
||||
================================= FAILURES =================================
|
||||
________________________ test_ehlo[smtp.gmail.com] _________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
assert b"smtp.gmail.com" in msg
|
||||
> assert 0 # for demo purposes
|
||||
@@ -580,10 +603,10 @@ So let's just do another run::
|
||||
test_module.py:6: AssertionError
|
||||
________________________ test_noop[smtp.gmail.com] _________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_noop(smtp):
|
||||
response, msg = smtp.noop()
|
||||
def test_noop(smtp_connection):
|
||||
response, msg = smtp_connection.noop()
|
||||
assert response == 250
|
||||
> assert 0 # for demo purposes
|
||||
E assert 0
|
||||
@@ -591,10 +614,10 @@ So let's just do another run::
|
||||
test_module.py:11: AssertionError
|
||||
________________________ test_ehlo[mail.python.org] ________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_ehlo(smtp):
|
||||
response, msg = smtp.ehlo()
|
||||
def test_ehlo(smtp_connection):
|
||||
response, msg = smtp_connection.ehlo()
|
||||
assert response == 250
|
||||
> assert b"smtp.gmail.com" in msg
|
||||
E AssertionError: assert b'smtp.gmail.com' in b'mail.python.org\nPIPELINING\nSIZE 51200000\nETRN\nSTARTTLS\nAUTH DIGEST-MD5 NTLM CRAM-MD5\nENHANCEDSTATUSCODES\n8BITMIME\nDSN\nSMTPUTF8'
|
||||
@@ -604,10 +627,10 @@ So let's just do another run::
|
||||
finalizing <smtplib.SMTP object at 0xdeadbeef>
|
||||
________________________ test_noop[mail.python.org] ________________________
|
||||
|
||||
smtp = <smtplib.SMTP object at 0xdeadbeef>
|
||||
smtp_connection = <smtplib.SMTP object at 0xdeadbeef>
|
||||
|
||||
def test_noop(smtp):
|
||||
response, msg = smtp.noop()
|
||||
def test_noop(smtp_connection):
|
||||
response, msg = smtp_connection.noop()
|
||||
assert response == 250
|
||||
> assert 0 # for demo purposes
|
||||
E assert 0
|
||||
@@ -618,7 +641,7 @@ So let's just do another run::
|
||||
4 failed in 0.12 seconds
|
||||
|
||||
We see that our two test functions each ran twice, against the different
|
||||
``smtp`` instances. Note also, that with the ``mail.python.org``
|
||||
``smtp_connection`` instances. Note also, that with the ``mail.python.org``
|
||||
connection the second test fails in ``test_ehlo`` because a
|
||||
different server string is expected than what arrived.
|
||||
|
||||
@@ -709,7 +732,7 @@ Running this test will *skip* the invocation of ``data_set`` with value ``2``::
|
||||
|
||||
$ pytest test_fixture_marks.py -v
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 3 items
|
||||
@@ -730,46 +753,46 @@ can use other fixtures themselves. This contributes to a modular design
|
||||
of your fixtures and allows re-use of framework-specific fixtures across
|
||||
many projects. As a simple example, we can extend the previous example
|
||||
and instantiate an object ``app`` where we stick the already defined
|
||||
``smtp`` resource into it::
|
||||
``smtp_connection`` resource into it::
|
||||
|
||||
# content of test_appsetup.py
|
||||
|
||||
import pytest
|
||||
|
||||
class App(object):
|
||||
def __init__(self, smtp):
|
||||
self.smtp = smtp
|
||||
def __init__(self, smtp_connection):
|
||||
self.smtp_connection = smtp_connection
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def app(smtp):
|
||||
return App(smtp)
|
||||
def app(smtp_connection):
|
||||
return App(smtp_connection)
|
||||
|
||||
def test_smtp_exists(app):
|
||||
assert app.smtp
|
||||
def test_smtp_connection_exists(app):
|
||||
assert app.smtp_connection
|
||||
|
||||
Here we declare an ``app`` fixture which receives the previously defined
|
||||
``smtp`` fixture and instantiates an ``App`` object with it. Let's run it::
|
||||
``smtp_connection`` fixture and instantiates an ``App`` object with it. Let's run it::
|
||||
|
||||
$ pytest -v test_appsetup.py
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 2 items
|
||||
|
||||
test_appsetup.py::test_smtp_exists[smtp.gmail.com] PASSED [ 50%]
|
||||
test_appsetup.py::test_smtp_exists[mail.python.org] PASSED [100%]
|
||||
test_appsetup.py::test_smtp_connection_exists[smtp.gmail.com] PASSED [ 50%]
|
||||
test_appsetup.py::test_smtp_connection_exists[mail.python.org] PASSED [100%]
|
||||
|
||||
========================= 2 passed in 0.12 seconds =========================
|
||||
|
||||
Due to the parametrization of ``smtp`` the test will run twice with two
|
||||
Due to the parametrization of ``smtp_connection``, the test will run twice with two
|
||||
different ``App`` instances and respective smtp servers. There is no
|
||||
need for the ``app`` fixture to be aware of the ``smtp`` parametrization
|
||||
as pytest will fully analyse the fixture dependency graph.
|
||||
need for the ``app`` fixture to be aware of the ``smtp_connection``
|
||||
parametrization because pytest will fully analyse the fixture dependency graph.
|
||||
|
||||
Note, that the ``app`` fixture has a scope of ``module`` and uses a
|
||||
module-scoped ``smtp`` fixture. The example would still work if ``smtp``
|
||||
was cached on a ``session`` scope: it is fine for fixtures to use
|
||||
module-scoped ``smtp_connection`` fixture. The example would still work if
|
||||
``smtp_connection`` was cached on a ``session`` scope: it is fine for fixtures to use
|
||||
"broader" scoped fixtures but not the other way round:
|
||||
A session-scoped fixture could not use a module-scoped one in a
|
||||
meaningful way.
|
||||
@@ -788,7 +811,7 @@ first execute with one instance and then finalizers are called
|
||||
before the next fixture instance is created. Among other things,
|
||||
this eases testing of applications which create and use global state.
|
||||
|
||||
The following example uses two parametrized fixture, one of which is
|
||||
The following example uses two parametrized fixtures, one of which is
|
||||
scoped on a per-module basis, and all the functions perform ``print`` calls
|
||||
to show the setup/teardown flow::
|
||||
|
||||
@@ -821,7 +844,7 @@ Let's run the tests in verbose mode and with looking at the print-output::
|
||||
|
||||
$ pytest -v -s test_module.py
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.6
|
||||
cachedir: .pytest_cache
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collecting ... collected 8 items
|
||||
@@ -943,7 +966,7 @@ a generic feature of the mark mechanism:
|
||||
Note that the assigned variable *must* be called ``pytestmark``, assigning e.g.
|
||||
``foomark`` will not activate the fixtures.
|
||||
|
||||
Lastly you can put fixtures required by all tests in your project
|
||||
It is also possible to put fixtures required by all tests in your project
|
||||
into an ini-file:
|
||||
|
||||
.. code-block:: ini
|
||||
@@ -953,6 +976,22 @@ into an ini-file:
|
||||
usefixtures = cleandir
|
||||
|
||||
|
||||
.. warning::
|
||||
|
||||
Note this mark has no effect in **fixture functions**. For example,
|
||||
this **will not work as expected**:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@pytest.mark.usefixtures("my_other_fixture")
|
||||
@pytest.fixture
|
||||
def my_fixture_that_sadly_wont_use_my_other_fixture():
|
||||
...
|
||||
|
||||
Currently this will not generate any error or warning, but this is intended
|
||||
to be handled by `#3664 <https://github.com/pytest-dev/pytest/issues/3664>`_.
|
||||
|
||||
|
||||
.. _`autouse`:
|
||||
.. _`autouse fixtures`:
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ pytest-2.3: reasoning for fixture/funcarg evolution
|
||||
|
||||
**Target audience**: Reading this document requires basic knowledge of
|
||||
python testing, xUnit setup methods and the (previous) basic pytest
|
||||
funcarg mechanism, see http://pytest.org/2.2.4/funcargs.html
|
||||
funcarg mechanism, see https://docs.pytest.org/en/latest/historical-notes.html#funcargs-and-pytest-funcarg.
|
||||
If you are new to pytest, then you can simply ignore this
|
||||
section and read the other sections.
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
from __future__ import print_function
|
||||
import textwrap
|
||||
import inspect
|
||||
|
||||
|
||||
class Writer(object):
|
||||
|
||||
def __init__(self, clsname):
|
||||
self.clsname = clsname
|
||||
|
||||
def __enter__(self):
|
||||
self.file = open("%s.api" % self.clsname, "w")
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.file.close()
|
||||
print("wrote", self.file.name)
|
||||
|
||||
def line(self, line):
|
||||
self.file.write(line + "\n")
|
||||
|
||||
def docmethod(self, method):
|
||||
doc = " ".join(method.__doc__.split())
|
||||
indent = " "
|
||||
w = textwrap.TextWrapper(initial_indent=indent, subsequent_indent=indent)
|
||||
|
||||
spec = inspect.getargspec(method)
|
||||
del spec.args[0]
|
||||
self.line(".. py:method:: " + method.__name__ + inspect.formatargspec(*spec))
|
||||
self.line("")
|
||||
self.line(w.fill(doc))
|
||||
self.line("")
|
||||
|
||||
|
||||
def pytest_funcarg__a(request):
|
||||
with Writer("request") as writer:
|
||||
writer.docmethod(request.getfixturevalue)
|
||||
writer.docmethod(request.cached_setup)
|
||||
writer.docmethod(request.addfinalizer)
|
||||
writer.docmethod(request.applymarker)
|
||||
|
||||
|
||||
def test_hello(a):
|
||||
pass
|
||||
@@ -1,7 +1,7 @@
|
||||
Installation and Getting Started
|
||||
===================================
|
||||
|
||||
**Pythons**: Python 2.7, 3.4, 3.5, 3.6, Jython, PyPy-2.3
|
||||
**Pythons**: Python 2.7, 3.4, 3.5, 3.6, 3.7, Jython, PyPy-2.3
|
||||
|
||||
**Platforms**: Unix/Posix and Windows
|
||||
|
||||
@@ -27,7 +27,7 @@ Install ``pytest``
|
||||
2. Check that you installed the correct version::
|
||||
|
||||
$ pytest --version
|
||||
This is pytest version 3.x.y, imported from $PYTHON_PREFIX/lib/python3.5/site-packages/pytest.py
|
||||
This is pytest version 3.x.y, imported from $PYTHON_PREFIX/lib/python3.6/site-packages/pytest.py
|
||||
|
||||
.. _`simpletest`:
|
||||
|
||||
|
||||
@@ -4,6 +4,27 @@
|
||||
Good Integration Practices
|
||||
=================================================
|
||||
|
||||
Install package with pip
|
||||
-------------------------------------------------
|
||||
|
||||
For development, we recommend to use virtualenv_ environments and pip_
|
||||
for installing your application and any dependencies
|
||||
as well as the ``pytest`` package itself. This ensures your code and
|
||||
dependencies are isolated from the system Python installation.
|
||||
|
||||
First you need to place a ``setup.py`` file in the root of your package with the following minimum content::
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name="PACKAGENAME", packages=find_packages())
|
||||
|
||||
Where ``PACKAGENAME`` is the name of your package. You can then install your package in "editable" mode by running from the same directory::
|
||||
|
||||
pip install -e .
|
||||
|
||||
which lets you change your source code (both tests and application) and rerun tests at will.
|
||||
This is similar to running ``python setup.py develop`` or ``conda develop`` in that it installs
|
||||
your package using a symlink to your development code.
|
||||
|
||||
.. _`test discovery`:
|
||||
.. _`Python test discovery`:
|
||||
@@ -177,19 +198,6 @@ Note that this layout also works in conjunction with the ``src`` layout mentione
|
||||
tox
|
||||
------
|
||||
|
||||
For development, we recommend to use virtualenv_ environments and pip_
|
||||
for installing your application and any dependencies
|
||||
as well as the ``pytest`` package itself. This ensures your code and
|
||||
dependencies are isolated from the system Python installation.
|
||||
|
||||
You can then install your package in "editable" mode::
|
||||
|
||||
pip install -e .
|
||||
|
||||
which lets you change your source code (both tests and application) and rerun tests at will.
|
||||
This is similar to running `python setup.py develop` or `conda develop` in that it installs
|
||||
your package using a symlink to your development code.
|
||||
|
||||
Once you are done with your work and want to make sure that your actual
|
||||
package passes all tests you may want to look into `tox`_, the
|
||||
virtualenv test automation tool and its `pytest support
|
||||
@@ -282,7 +290,7 @@ your own setuptools Test command for invoking pytest.
|
||||
setup(
|
||||
# ...,
|
||||
tests_require=["pytest"],
|
||||
cmdclass={"test": PyTest},
|
||||
cmdclass={"pytest": PyTest},
|
||||
)
|
||||
|
||||
Now if you run::
|
||||
|
||||
@@ -175,3 +175,13 @@ Previous to version 2.4 to set a break point in code one needed to use ``pytest.
|
||||
This is no longer needed and one can use the native ``import pdb;pdb.set_trace()`` call directly.
|
||||
|
||||
For more details see :ref:`breakpoints`.
|
||||
|
||||
"compat" properties
|
||||
-------------------
|
||||
|
||||
.. deprecated:: 3.9
|
||||
|
||||
Access of ``Module``, ``Function``, ``Class``, ``Instance``, ``File`` and ``Item`` through ``Node`` instances have long
|
||||
been documented as deprecated, but started to emit warnings from pytest ``3.9`` and onward.
|
||||
|
||||
Users should just ``import pytest`` and access those objects using the ``pytest`` module.
|
||||
|
||||
@@ -26,28 +26,48 @@ which also serve as documentation.
|
||||
:ref:`fixtures <fixtures>`.
|
||||
|
||||
|
||||
.. currentmodule:: _pytest.mark.structures
|
||||
.. autoclass:: Mark
|
||||
:members:
|
||||
:noindex:
|
||||
Raising errors on unknown marks: --strict
|
||||
-----------------------------------------
|
||||
|
||||
When the ``--strict`` command-line flag is passed, any marks not registered in the ``pytest.ini`` file will trigger an error.
|
||||
|
||||
Marks can be registered like this:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
markers =
|
||||
slow
|
||||
serial
|
||||
|
||||
This can be used to prevent users mistyping mark names by accident. Test suites that want to enforce this
|
||||
should add ``--strict`` to ``addopts``:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
addopts = --strict
|
||||
markers =
|
||||
slow
|
||||
serial
|
||||
|
||||
|
||||
.. `marker-iteration`
|
||||
.. _marker-revamp:
|
||||
|
||||
Marker revamp and iteration
|
||||
---------------------------
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
pytest's marker implementation traditionally worked by simply updating the ``__dict__`` attribute of functions to add markers, in a cumulative manner. As a result of the this, markers would unintendely be passed along class hierarchies in surprising ways plus the API for retriving them was inconsistent, as markers from parameterization would be stored differently than markers applied using the ``@pytest.mark`` decorator and markers added via ``node.add_marker``.
|
||||
pytest's marker implementation traditionally worked by simply updating the ``__dict__`` attribute of functions to cumulatively add markers. As a result, markers would unintentionally be passed along class hierarchies in surprising ways. Further, the API for retrieving them was inconsistent, as markers from parameterization would be stored differently than markers applied using the ``@pytest.mark`` decorator and markers added via ``node.add_marker``.
|
||||
|
||||
This state of things made it technically next to impossible to use data from markers correctly without having a deep understanding of the internals, leading to subtle and hard to understand bugs in more advanced usages.
|
||||
|
||||
Depending on how a marker got declared/changed one would get either a ``MarkerInfo`` which might contain markers from sibling classes,
|
||||
``MarkDecorators`` when marks came from parameterization or from a ``node.add_marker`` call, discarding prior marks. Also ``MarkerInfo`` acts like a single mark, when it in fact represents a merged view on multiple marks with the same name.
|
||||
|
||||
On top of that markers where not accessible the same way for modules, classes, and functions/methods,
|
||||
in fact, markers where only accessible in functions, even if they where declared on classes/modules.
|
||||
On top of that markers were not accessible the same way for modules, classes, and functions/methods.
|
||||
In fact, markers were only accessible in functions, even if they were declared on classes/modules.
|
||||
|
||||
A new API to access markers has been introduced in pytest 3.6 in order to solve the problems with the initial design, providing :func:`_pytest.nodes.Node.iter_markers` method to iterate over markers in a consistent manner and reworking the internals, which solved great deal of problems with the initial design.
|
||||
|
||||
@@ -58,14 +78,14 @@ Updating code
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The old ``Node.get_marker(name)`` function is considered deprecated because it returns an internal ``MarkerInfo`` object
|
||||
which contains the merged name, ``*args`` and ``**kwargs**`` of all the markers which apply to that node.
|
||||
which contains the merged name, ``*args`` and ``**kwargs`` of all the markers which apply to that node.
|
||||
|
||||
In general there are two scenarios on how markers should be handled:
|
||||
|
||||
1. Marks overwrite each other. Order matters but you only want to think of your mark as a single item. E.g.
|
||||
``log_level('info')`` at a module level can be overwritten by ``log_level('debug')`` for a specific test.
|
||||
|
||||
In this case replace use ``Node.get_closest_marker(name)``:
|
||||
In this case, use ``Node.get_closest_marker(name)``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -79,7 +99,7 @@ In general there are two scenarios on how markers should be handled:
|
||||
if marker:
|
||||
level = marker.args[0]
|
||||
|
||||
2. Marks compose additive. E.g. ``skipif(condition)`` marks means you just want to evaluate all of them,
|
||||
2. Marks compose in an additive manner. E.g. ``skipif(condition)`` marks mean you just want to evaluate all of them,
|
||||
order doesn't even matter. You probably want to think of your marks as a set here.
|
||||
|
||||
In this case iterate over each mark and handle their ``*args`` and ``**kwargs`` individually.
|
||||
@@ -109,27 +129,27 @@ Here is a non-exhaustive list of issues fixed by the new implementation:
|
||||
|
||||
* Marks don't pick up nested classes (`#199 <https://github.com/pytest-dev/pytest/issues/199>`_).
|
||||
|
||||
* markers stains on all related classes (`#568 <https://github.com/pytest-dev/pytest/issues/568>`_).
|
||||
* Markers stain on all related classes (`#568 <https://github.com/pytest-dev/pytest/issues/568>`_).
|
||||
|
||||
* combining marks - args and kwargs calculation (`#2897 <https://github.com/pytest-dev/pytest/issues/2897>`_).
|
||||
* Combining marks - args and kwargs calculation (`#2897 <https://github.com/pytest-dev/pytest/issues/2897>`_).
|
||||
|
||||
* ``request.node.get_marker('name')`` returns ``None`` for markers applied in classes (`#902 <https://github.com/pytest-dev/pytest/issues/902>`_).
|
||||
|
||||
* marks applied in parametrize are stored as markdecorator (`#2400 <https://github.com/pytest-dev/pytest/issues/2400>`_).
|
||||
* Marks applied in parametrize are stored as markdecorator (`#2400 <https://github.com/pytest-dev/pytest/issues/2400>`_).
|
||||
|
||||
* fix marker interaction in a backward incompatible way (`#1670 <https://github.com/pytest-dev/pytest/issues/1670>`_).
|
||||
* Fix marker interaction in a backward incompatible way (`#1670 <https://github.com/pytest-dev/pytest/issues/1670>`_).
|
||||
|
||||
* Refactor marks to get rid of the current "marks transfer" mechanism (`#2363 <https://github.com/pytest-dev/pytest/issues/2363>`_).
|
||||
|
||||
* Introduce FunctionDefinition node, use it in generate_tests (`#2522 <https://github.com/pytest-dev/pytest/issues/2522>`_).
|
||||
|
||||
* remove named marker attributes and collect markers in items (`#891 <https://github.com/pytest-dev/pytest/issues/891>`_).
|
||||
* Remove named marker attributes and collect markers in items (`#891 <https://github.com/pytest-dev/pytest/issues/891>`_).
|
||||
|
||||
* skipif mark from parametrize hides module level skipif mark (`#1540 <https://github.com/pytest-dev/pytest/issues/1540>`_).
|
||||
|
||||
* skipif + parametrize not skipping tests (`#1296 <https://github.com/pytest-dev/pytest/issues/1296>`_).
|
||||
|
||||
* marker transfer incompatible with inheritance (`#535 <https://github.com/pytest-dev/pytest/issues/535>`_).
|
||||
* Marker transfer incompatible with inheritance (`#535 <https://github.com/pytest-dev/pytest/issues/535>`_).
|
||||
|
||||
More details can be found in the `original PR <https://github.com/pytest-dev/pytest/pull/3317>`_.
|
||||
|
||||
|
||||
@@ -114,6 +114,10 @@ Let's run this::
|
||||
The one parameter set which caused a failure previously now
|
||||
shows up as an "xfailed (expected to fail)" test.
|
||||
|
||||
In case the values provided to ``parametrize`` result in an empty list - for
|
||||
example, if they're dynamically generated by some function - the behaviour of
|
||||
pytest is defined by the :confval:`empty_parameter_set_mark` option.
|
||||
|
||||
To get all combinations of multiple parametrized arguments you can stack
|
||||
``parametrize`` decorators::
|
||||
|
||||
|
||||
@@ -69,17 +69,15 @@ You may also discover more plugins through a `pytest- pypi.python.org search`_.
|
||||
Requiring/Loading plugins in a test module or conftest file
|
||||
-----------------------------------------------------------
|
||||
|
||||
You can require plugins in a test module or a conftest file like this::
|
||||
You can require plugins in a test module or a conftest file like this:
|
||||
|
||||
pytest_plugins = "myapp.testsupport.myplugin",
|
||||
.. code-block:: python
|
||||
|
||||
pytest_plugins = ("myapp.testsupport.myplugin",)
|
||||
|
||||
When the test module or conftest plugin is loaded the specified plugins
|
||||
will be loaded as well.
|
||||
|
||||
pytest_plugins = "myapp.testsupport.myplugin"
|
||||
|
||||
which will import the specified module as a ``pytest`` plugin.
|
||||
|
||||
.. note::
|
||||
Requiring plugins using a ``pytest_plugins`` variable in non-root
|
||||
``conftest.py`` files is deprecated. See
|
||||
|
||||
@@ -84,6 +84,12 @@ pytest.warns
|
||||
.. autofunction:: pytest.warns(expected_warning: Exception, [match])
|
||||
:with:
|
||||
|
||||
pytest.freeze_includes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Tutorial**: :ref:`freezing-pytest`.
|
||||
|
||||
.. autofunction:: pytest.freeze_includes
|
||||
|
||||
.. _`marks ref`:
|
||||
|
||||
@@ -161,6 +167,25 @@ Skip a test function if a condition is ``True``.
|
||||
:keyword str reason: Reason why the test function is being skipped.
|
||||
|
||||
|
||||
.. _`pytest.mark.usefixtures ref`:
|
||||
|
||||
pytest.mark.usefixtures
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Tutorial**: :ref:`usefixtures`.
|
||||
|
||||
Mark a test function as using the given fixture names.
|
||||
|
||||
.. warning::
|
||||
|
||||
This mark has no effect when applied
|
||||
to a **fixture** function.
|
||||
|
||||
.. py:function:: pytest.mark.usefixtures(*names)
|
||||
|
||||
:param args: the names of the fixture to use, as strings
|
||||
|
||||
|
||||
.. _`pytest.mark.xfail ref`:
|
||||
|
||||
pytest.mark.xfail
|
||||
@@ -441,7 +466,7 @@ To use it, include in your top-most ``conftest.py`` file::
|
||||
|
||||
|
||||
.. autoclass:: Testdir()
|
||||
:members: runpytest,runpytest_subprocess,runpytest_inprocess,makeconftest,makepyfile
|
||||
:members:
|
||||
|
||||
.. autoclass:: RunResult()
|
||||
:members:
|
||||
@@ -592,6 +617,8 @@ Session related reporting hooks:
|
||||
.. autofunction:: pytest_terminal_summary
|
||||
.. autofunction:: pytest_fixture_setup
|
||||
.. autofunction:: pytest_fixture_post_finalizer
|
||||
.. autofunction:: pytest_logwarning
|
||||
.. autofunction:: pytest_warning_captured
|
||||
|
||||
And here is the central hook for reporting about
|
||||
test execution:
|
||||
@@ -733,7 +760,7 @@ Node
|
||||
Parser
|
||||
~~~~~~
|
||||
|
||||
.. autoclass:: _pytest.config.Parser()
|
||||
.. autoclass:: _pytest.config.argparsing.Parser()
|
||||
:members:
|
||||
|
||||
PluginManager
|
||||
@@ -768,7 +795,7 @@ TestReport
|
||||
_Result
|
||||
~~~~~~~
|
||||
|
||||
.. autoclass:: pluggy._Result
|
||||
.. autoclass:: pluggy.callers._Result
|
||||
:members:
|
||||
|
||||
Special Variables
|
||||
@@ -845,8 +872,13 @@ Contains comma-separated list of modules that should be loaded as plugins:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
export PYTEST_PLUGINS=mymodule.plugin,xdisst
|
||||
export PYTEST_PLUGINS=mymodule.plugin,xdist
|
||||
|
||||
PYTEST_DISABLE_PLUGIN_AUTOLOAD
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When set, disables plugin auto-loading through setuptools entrypoints. Only explicitly specified plugins will be
|
||||
loaded.
|
||||
|
||||
PYTEST_CURRENT_TEST
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -916,6 +948,7 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||
|
||||
* ``classic``: classic pytest output.
|
||||
* ``progress``: like classic pytest output, but with a progress indicator.
|
||||
* ``count``: like progress, but shows progress as the number of tests completed instead of a percent.
|
||||
|
||||
The default is ``progress``, but you can fallback to ``classic`` if you prefer or
|
||||
the new mode is causing unexpected problems:
|
||||
@@ -949,6 +982,7 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||
|
||||
* ``skip`` skips tests with an empty parameterset (default)
|
||||
* ``xfail`` marks tests with an empty parameterset as xfail(run=False)
|
||||
* ``fail_at_collect`` raises an exception if parametrize collects an empty parameter set
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
@@ -1210,7 +1244,8 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||
.. confval:: python_classes
|
||||
|
||||
One or more name prefixes or glob-style patterns determining which classes
|
||||
are considered for test collection. By default, pytest will consider any
|
||||
are considered for test collection. Search for multiple glob patterns by
|
||||
adding a space between patterns. By default, pytest will consider any
|
||||
class prefixed with ``Test`` as a test collection. Here is an example of how
|
||||
to collect tests from classes that end in ``Suite``:
|
||||
|
||||
@@ -1227,15 +1262,33 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||
.. confval:: python_files
|
||||
|
||||
One or more Glob-style file patterns determining which python files
|
||||
are considered as test modules. By default, pytest will consider
|
||||
any file matching with ``test_*.py`` and ``*_test.py`` globs as a test
|
||||
module.
|
||||
are considered as test modules. Search for multiple glob patterns by
|
||||
adding a space between patterns:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
python_files = test_*.py check_*.py example_*.py
|
||||
|
||||
Or one per line:
|
||||
|
||||
.. code-block:: ini
|
||||
|
||||
[pytest]
|
||||
python_files =
|
||||
test_*.py
|
||||
check_*.py
|
||||
example_*.py
|
||||
|
||||
By default, files matching ``test_*.py`` and ``*_test.py`` will be considered
|
||||
test modules.
|
||||
|
||||
|
||||
.. confval:: python_functions
|
||||
|
||||
One or more name prefixes or glob-patterns determining which test functions
|
||||
and methods are considered tests. By default, pytest will consider any
|
||||
and methods are considered tests. Search for multiple glob patterns by
|
||||
adding a space between patterns. By default, pytest will consider any
|
||||
function prefixed with ``test`` as a test. Here is an example of how
|
||||
to collect test functions and methods that end in ``_test``:
|
||||
|
||||
|
||||
@@ -58,18 +58,20 @@ by calling the ``pytest.skip(reason)`` function:
|
||||
if not valid_config():
|
||||
pytest.skip("unsupported configuration")
|
||||
|
||||
The imperative method is useful when it is not possible to evaluate the skip condition
|
||||
during import time.
|
||||
|
||||
It is also possible to skip the whole module using
|
||||
``pytest.skip(reason, allow_module_level=True)`` at the module level:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import sys
|
||||
import pytest
|
||||
|
||||
if not pytest.config.getoption("--custom-flag"):
|
||||
pytest.skip("--custom-flag is missing, skipping tests", allow_module_level=True)
|
||||
if not sys.platform.startswith("win"):
|
||||
pytest.skip("skipping windows-only tests", allow_module_level=True)
|
||||
|
||||
The imperative method is useful when it is not possible to evaluate the skip condition
|
||||
during import time.
|
||||
|
||||
**Reference**: :ref:`pytest.mark.skip ref`
|
||||
|
||||
@@ -80,11 +82,11 @@ during import time.
|
||||
|
||||
If you wish to skip something conditionally then you can use ``skipif`` instead.
|
||||
Here is an example of marking a test function to be skipped
|
||||
when run on a Python3.6 interpreter::
|
||||
when run on an interpreter earlier than Python3.6 ::
|
||||
|
||||
import sys
|
||||
@pytest.mark.skipif(sys.version_info < (3,6),
|
||||
reason="requires python3.6")
|
||||
reason="requires python3.6 or higher")
|
||||
def test_function():
|
||||
...
|
||||
|
||||
@@ -136,12 +138,6 @@ You can use the ``skipif`` marker (as any other marker) on classes::
|
||||
If the condition is ``True``, this marker will produce a skip result for
|
||||
each of the test methods of that class.
|
||||
|
||||
.. warning::
|
||||
|
||||
The use of ``skipif`` on classes that use inheritance is strongly
|
||||
discouraged. `A Known bug <https://github.com/pytest-dev/pytest/issues/568>`_
|
||||
in pytest's markers may cause unexpected behavior in super classes.
|
||||
|
||||
If you want to skip all test functions of a module, you may use
|
||||
the ``pytestmark`` name on the global level:
|
||||
|
||||
@@ -283,7 +279,7 @@ on a particular platform::
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to be more specific as to why the test is failing, you can specify
|
||||
a single exception, or a list of exceptions, in the ``raises`` argument.
|
||||
a single exception, or a tuple of exceptions, in the ``raises`` argument.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
@@ -14,6 +14,9 @@ Talks and Tutorials
|
||||
Books
|
||||
---------------------------------------------
|
||||
|
||||
- `pytest Quick Start Guide, by Bruno Oliveira (2018)
|
||||
<https://www.packtpub.com/web-development/pytest-quick-start-guide>`_.
|
||||
|
||||
- `Python Testing with pytest, by Brian Okken (2017)
|
||||
<https://pragprog.com/book/bopytest/python-testing-with-pytest>`_.
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
===============================================
|
||||
ATTIC documentation
|
||||
===============================================
|
||||
|
||||
XXX REVIEW and remove the below XXX
|
||||
|
||||
Customizing the testing process
|
||||
===============================
|
||||
|
||||
writing conftest.py files
|
||||
-----------------------------------
|
||||
|
||||
You may put conftest.py files containing project-specific
|
||||
configuration in your project's root directory, it's usually
|
||||
best to put it just into the same directory level as your
|
||||
topmost ``__init__.py``. In fact, ``pytest`` performs
|
||||
an "upwards" search starting from the directory that you specify
|
||||
to be tested and will lookup configuration values right-to-left.
|
||||
You may have options that reside e.g. in your home directory
|
||||
but note that project specific settings will be considered
|
||||
first. There is a flag that helps you debugging your
|
||||
conftest.py configurations::
|
||||
|
||||
pytest --trace-config
|
||||
|
||||
|
||||
customizing the collecting and running process
|
||||
-----------------------------------------------
|
||||
|
||||
To introduce different test items you can create
|
||||
one or more ``conftest.py`` files in your project.
|
||||
When the collection process traverses directories
|
||||
and modules the default collectors will produce
|
||||
custom Collectors and Items if they are found
|
||||
in a local ``conftest.py`` file.
|
||||
|
||||
|
||||
Customizing the collection process in a module
|
||||
----------------------------------------------
|
||||
|
||||
If you have a module where you want to take responsibility for
|
||||
collecting your own test Items and possibly even for executing
|
||||
a test then you can provide `generative tests`_ that yield
|
||||
callables and possibly arguments as a tuple. This is especially
|
||||
useful for calling application test machinery with different
|
||||
parameter sets but counting each of the calls as a separate
|
||||
tests.
|
||||
|
||||
.. _`generative tests`: features.html#generative-tests
|
||||
|
||||
The other extension possibility is about
|
||||
specifying a custom test ``Item`` class which
|
||||
is responsible for setting up and executing an underlying
|
||||
test. Or you can extend the collection process for a whole
|
||||
directory tree by putting Items in a ``conftest.py`` configuration file.
|
||||
The collection process dynamically consults the *chain of conftest.py*
|
||||
modules to determine collectors and items at ``Directory``, ``Module``,
|
||||
``Class``, ``Function`` or ``Generator`` level respectively.
|
||||
|
||||
Customizing execution of Items and Functions
|
||||
----------------------------------------------------
|
||||
|
||||
- ``pytest.Function`` test items control execution
|
||||
of a test function through its ``function.runtest()`` method.
|
||||
This method is responsible for performing setup and teardown
|
||||
("Test Fixtures") for a test Function.
|
||||
|
||||
- ``Function.execute(target, *args)`` methods are invoked by
|
||||
the default ``Function.run()`` to actually execute a python
|
||||
function with the given (usually empty set of) arguments.
|
||||
|
||||
.. _`py-dev mailing list`: http://codespeak.net/mailman/listinfo/py-dev
|
||||
|
||||
|
||||
.. _`test generators`: funcargs.html#test-generators
|
||||
|
||||
.. _`generative tests`:
|
||||
|
||||
generative tests: yielding parametrized tests
|
||||
====================================================
|
||||
|
||||
Deprecated since 1.0 in favour of `test generators`_.
|
||||
|
||||
*Generative tests* are test methods that are *generator functions* which
|
||||
``yield`` callables and their arguments. This is useful for running a
|
||||
test function multiple times against different parameters. Example::
|
||||
|
||||
def test_generative():
|
||||
for x in (42,17,49):
|
||||
yield check, x
|
||||
|
||||
def check(arg):
|
||||
assert arg % 7 == 0 # second generated tests fails!
|
||||
|
||||
Note that ``test_generative()`` will cause three tests
|
||||
to get run, notably ``check(42)``, ``check(17)`` and ``check(49)``
|
||||
of which the middle one will obviously fail.
|
||||
|
||||
To make it easier to distinguish the generated tests it is possible to specify an explicit name for them, like for example::
|
||||
|
||||
def test_generative():
|
||||
for x in (42,17,49):
|
||||
yield "case %d" % x, check, x
|
||||
|
||||
|
||||
disabling a test class
|
||||
----------------------
|
||||
|
||||
If you want to disable a complete test class you
|
||||
can set the class-level attribute ``disabled``.
|
||||
For example, in order to avoid running some tests on Win32::
|
||||
|
||||
class TestPosixOnly(object):
|
||||
disabled = sys.platform == 'win32'
|
||||
|
||||
def test_xxx(self):
|
||||
...
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content=" 1 ; URL=customize.html" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("UA-7597274-3");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content=" 1 ; URL=plugin/xdist.html" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("UA-7597274-3");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content=" 1 ; URL=customize.html" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("UA-7597274-3");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,33 +0,0 @@
|
||||
=======================================
|
||||
pytest documentation index
|
||||
=======================================
|
||||
|
||||
|
||||
features_: overview and discussion of features.
|
||||
|
||||
quickstart_: getting started with writing a simple test.
|
||||
|
||||
`talks, tutorials, examples`_: tutorial examples, slides
|
||||
|
||||
funcargs_: powerful parametrized test function setup
|
||||
|
||||
`plugins`_: list of available plugins with usage examples and feature details.
|
||||
|
||||
customize_: configuration, customization, extensions
|
||||
|
||||
changelog_: history of changes covering last releases
|
||||
|
||||
**Continuous Integration of pytest's own tests and plugins with Hudson**:
|
||||
|
||||
`http://hudson.testrun.org/view/pytest`_
|
||||
|
||||
.. _`http://hudson.testrun.org/view/pytest`: http://hudson.testrun.org/view/pytest/
|
||||
|
||||
|
||||
.. _changelog: ../changelog.html
|
||||
.. _`plugins`: plugin/index.html
|
||||
.. _`talks, tutorials, examples`: talks.html
|
||||
.. _quickstart: quickstart.html
|
||||
.. _features: features.html
|
||||
.. _funcargs: funcargs.html
|
||||
.. _customize: customize.html
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
Mission
|
||||
====================================
|
||||
|
||||
``pytest`` strives to make testing a fun and no-boilerplate effort.
|
||||
|
||||
The tool is distributed as a `pytest` package. Its project independent
|
||||
``pytest`` command line tool helps you to:
|
||||
|
||||
* rapidly collect and run tests
|
||||
* run unit- or doctests, functional or integration tests
|
||||
* distribute tests to multiple environments
|
||||
* use local or global plugins for custom test types and setup
|
||||
@@ -1,230 +0,0 @@
|
||||
|
||||
produce code coverage reports using the 'coverage' package, including support for distributed testing.
|
||||
======================================================================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
This plugin produces coverage reports. It supports centralised testing and distributed testing in
|
||||
both load and each modes. It also supports coverage of subprocesses.
|
||||
|
||||
All features offered by the coverage package should be available, either through pytest-cov or
|
||||
through coverage's config file.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The `pytest-cov`_ package may be installed with pip or easy_install::
|
||||
|
||||
pip install pytest-cov
|
||||
easy_install pytest-cov
|
||||
|
||||
.. _`pytest-cov`: https://pypi.org/project/pytest-cov/
|
||||
|
||||
|
||||
Uninstallation
|
||||
--------------
|
||||
|
||||
Uninstalling packages is supported by pip::
|
||||
|
||||
pip uninstall pytest-cov
|
||||
|
||||
However easy_install does not provide an uninstall facility.
|
||||
|
||||
.. IMPORTANT::
|
||||
|
||||
Ensure that you manually delete the init_covmain.pth file in your
|
||||
site-packages directory.
|
||||
|
||||
This file starts coverage collection of subprocesses if appropriate during
|
||||
site initialization at python startup.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Centralised Testing
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Centralised testing will report on the combined coverage of the main process and all of it's
|
||||
subprocesses.
|
||||
|
||||
Running centralised testing::
|
||||
|
||||
pytest --cov myproj tests/
|
||||
|
||||
Shows a terminal report::
|
||||
|
||||
-------------------- coverage: platform linux2, python 2.6.4-final-0 ---------------------
|
||||
Name Stmts Miss Cover
|
||||
----------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94%
|
||||
myproj/feature4286 94 7 92%
|
||||
----------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
Distributed Testing: Load
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Distributed testing with dist mode set to load will report on the combined coverage of all slaves.
|
||||
The slaves may be spread out over any number of hosts and each slave may be located anywhere on the
|
||||
file system. Each slave will have it's subprocesses measured.
|
||||
|
||||
Running distributed testing with dist mode set to load::
|
||||
|
||||
pytest --cov myproj -n 2 tests/
|
||||
|
||||
Shows a terminal report::
|
||||
|
||||
-------------------- coverage: platform linux2, python 2.6.4-final-0 ---------------------
|
||||
Name Stmts Miss Cover
|
||||
----------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94%
|
||||
myproj/feature4286 94 7 92%
|
||||
----------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
Again but spread over different hosts and different directories::
|
||||
|
||||
pytest --cov myproj --dist load
|
||||
--tx ssh=memedough@host1//chdir=testenv1
|
||||
--tx ssh=memedough@host2//chdir=/tmp/testenv2//python=/tmp/env1/bin/python
|
||||
--rsyncdir myproj --rsyncdir tests --rsync examples
|
||||
tests/
|
||||
|
||||
Shows a terminal report::
|
||||
|
||||
-------------------- coverage: platform linux2, python 2.6.4-final-0 ---------------------
|
||||
Name Stmts Miss Cover
|
||||
----------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94%
|
||||
myproj/feature4286 94 7 92%
|
||||
----------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
Distributed Testing: Each
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Distributed testing with dist mode set to each will report on the combined coverage of all slaves.
|
||||
Since each slave is running all tests this allows generating a combined coverage report for multiple
|
||||
environments.
|
||||
|
||||
Running distributed testing with dist mode set to each::
|
||||
|
||||
pytest --cov myproj --dist each
|
||||
--tx popen//chdir=/tmp/testenv3//python=/usr/local/python27/bin/python
|
||||
--tx ssh=memedough@host2//chdir=/tmp/testenv4//python=/tmp/env2/bin/python
|
||||
--rsyncdir myproj --rsyncdir tests --rsync examples
|
||||
tests/
|
||||
|
||||
Shows a terminal report::
|
||||
|
||||
---------------------------------------- coverage ----------------------------------------
|
||||
platform linux2, python 2.6.5-final-0
|
||||
platform linux2, python 2.7.0-final-0
|
||||
Name Stmts Miss Cover
|
||||
----------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94%
|
||||
myproj/feature4286 94 7 92%
|
||||
----------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
Reporting
|
||||
---------
|
||||
|
||||
It is possible to generate any combination of the reports for a single test run.
|
||||
|
||||
The available reports are terminal (with or without missing line numbers shown), HTML, XML and
|
||||
annotated source code.
|
||||
|
||||
The terminal report without line numbers (default)::
|
||||
|
||||
pytest --cov-report term --cov myproj tests/
|
||||
|
||||
-------------------- coverage: platform linux2, python 2.6.4-final-0 ---------------------
|
||||
Name Stmts Miss Cover
|
||||
----------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94%
|
||||
myproj/feature4286 94 7 92%
|
||||
----------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
The terminal report with line numbers::
|
||||
|
||||
pytest --cov-report term-missing --cov myproj tests/
|
||||
|
||||
-------------------- coverage: platform linux2, python 2.6.4-final-0 ---------------------
|
||||
Name Stmts Miss Cover Missing
|
||||
--------------------------------------------------
|
||||
myproj/__init__ 2 0 100%
|
||||
myproj/myproj 257 13 94% 24-26, 99, 149, 233-236, 297-298, 369-370
|
||||
myproj/feature4286 94 7 92% 183-188, 197
|
||||
--------------------------------------------------
|
||||
TOTAL 353 20 94%
|
||||
|
||||
|
||||
The remaining three reports output to files without showing anything on the terminal (useful for
|
||||
when the output is going to a continuous integration server)::
|
||||
|
||||
pytest --cov-report html --cov-report xml --cov-report annotate --cov myproj tests/
|
||||
|
||||
|
||||
Coverage Data File
|
||||
------------------
|
||||
|
||||
The data file is erased at the beginning of testing to ensure clean data for each test run.
|
||||
|
||||
The data file is left at the end of testing so that it is possible to use normal coverage tools to
|
||||
examine it.
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
For distributed testing the slaves must have the pytest-cov package installed. This is needed since
|
||||
the plugin must be registered through setuptools / distribute for pytest to start the plugin on the
|
||||
slave.
|
||||
|
||||
For subprocess measurement environment variables must make it from the main process to the
|
||||
subprocess. The python used by the subprocess must have pytest-cov installed. The subprocess must
|
||||
do normal site initialization so that the environment variables can be detected and coverage
|
||||
started.
|
||||
|
||||
|
||||
Acknowledgments
|
||||
----------------
|
||||
|
||||
Holger Krekel for pytest with its distributed testing support.
|
||||
|
||||
Ned Batchelder for coverage and its ability to combine the coverage results of parallel runs.
|
||||
|
||||
Whilst this plugin has been built fresh from the ground up to support distributed testing it has
|
||||
been influenced by the work done on pytest-coverage (Ross Lawley, James Mills, Holger Krekel) and
|
||||
nose-cover (Jason Pellerin) which are other coverage plugins for pytest and nose respectively.
|
||||
|
||||
No doubt others have contributed to these tools as well.
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``--cov=path``
|
||||
measure coverage for filesystem path (multi-allowed)
|
||||
``--cov-report=type``
|
||||
type of report to generate: term, term-missing, annotate, html, xml (multi-allowed)
|
||||
``--cov-config=path``
|
||||
config file for coverage, default: .coveragerc
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
Write and report coverage data with the 'coverage' package.
|
||||
===========================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Note: Original code by Ross Lawley.
|
||||
|
||||
Install
|
||||
--------------
|
||||
|
||||
Use pip to (un)install::
|
||||
|
||||
pip install pytest-coverage
|
||||
pip uninstall pytest-coverage
|
||||
|
||||
or alternatively use easy_install to install::
|
||||
|
||||
easy_install pytest-coverage
|
||||
|
||||
|
||||
Usage
|
||||
-------------
|
||||
|
||||
To get full test coverage reports for a particular package type::
|
||||
|
||||
pytest --cover-report=report
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``--cover=COVERPACKAGES``
|
||||
(multi allowed) only include info from specified package.
|
||||
``--cover-report=REPORT_TYPE``
|
||||
html: Directory for html output.
|
||||
report: Output a text report.
|
||||
annotate: Annotate your source code for which lines were executed and which were not.
|
||||
xml: Output an xml report compatible with the cobertura plugin for hudson.
|
||||
``--cover-directory=DIRECTORY``
|
||||
Directory for the reports (html / annotate results) defaults to ./coverage
|
||||
``--cover-xml-file=XML_FILE``
|
||||
File for the xml report defaults to ./coverage.xml
|
||||
``--cover-show-missing``
|
||||
Show missing files
|
||||
``--cover-ignore-errors=IGNORE_ERRORS``
|
||||
Ignore errors of finding source files for code.
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,6 +0,0 @@
|
||||
pytest_django plugin (EXTERNAL)
|
||||
==========================================
|
||||
|
||||
pytest_django is a plugin for ``pytest`` that provides a set of useful tools for testing Django applications, checkout Ben Firshman's `pytest_django github page`_.
|
||||
|
||||
.. _`pytest_django github page`: http://github.com/bfirsh/pytest_django/tree/master
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
report test coverage using the 'figleaf' package.
|
||||
=================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Install
|
||||
---------------
|
||||
|
||||
To install the plugin issue::
|
||||
|
||||
easy_install pytest-figleaf # or
|
||||
pip install pytest-figleaf
|
||||
|
||||
and if you are using pip you can also uninstall::
|
||||
|
||||
pip uninstall pytest-figleaf
|
||||
|
||||
|
||||
Usage
|
||||
---------------
|
||||
|
||||
After installation you can simply type::
|
||||
|
||||
pytest --figleaf [...]
|
||||
|
||||
to enable figleaf coverage in your test run. A default ".figleaf" data file
|
||||
and "html" directory will be created. You can use command line options
|
||||
to control where data and html files are created.
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``--figleaf``
|
||||
trace python coverage with figleaf and write HTML for files below the current working dir
|
||||
``--fig-data=dir``
|
||||
set tracing file, default: ".figleaf".
|
||||
``--fig-html=dir``
|
||||
set html reporting dir, default "html".
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,36 +0,0 @@
|
||||
|
||||
provide version info, conftest/environment config names.
|
||||
========================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``--version``
|
||||
display py lib version and import information.
|
||||
``-p name``
|
||||
early-load given plugin (multi-allowed).
|
||||
``--trace-config``
|
||||
trace considerations of conftest.py files.
|
||||
``--debug``
|
||||
generate and show internal debugging information.
|
||||
``--help-config``
|
||||
show available conftest.py and ENV-variable names.
|
||||
|
||||
Start improving this plugin in 30 seconds
|
||||
=========================================
|
||||
|
||||
|
||||
1. Download `pytest_helpconfig.py`_ plugin source code
|
||||
2. put it somewhere as ``pytest_helpconfig.py`` into your import path
|
||||
3. a subsequent ``pytest`` run will use your local version
|
||||
|
||||
Checkout customize_, other plugins_ or `get in contact`_.
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,68 +0,0 @@
|
||||
|
||||
advanced python testing
|
||||
=======================
|
||||
|
||||
skipping_ advanced skipping for python test functions, classes or modules.
|
||||
|
||||
mark_ generic mechanism for marking python functions.
|
||||
|
||||
pdb_ interactive debugging with the Python Debugger.
|
||||
|
||||
figleaf_ (external) report test coverage using the 'figleaf' package.
|
||||
|
||||
monkeypatch_ safely patch object attributes, dicts and environment variables.
|
||||
|
||||
coverage_ (external) Write and report coverage data with the 'coverage' package.
|
||||
|
||||
cov_ (external) produce code coverage reports using the 'coverage' package, including support for distributed testing.
|
||||
|
||||
capture_ configurable per-test stdout/stderr capturing mechanisms.
|
||||
|
||||
capturelog_ (external) capture output of logging module.
|
||||
|
||||
recwarn_ helpers for asserting deprecation and other warnings.
|
||||
|
||||
tmpdir_ provide temporary directories to test functions.
|
||||
|
||||
|
||||
distributed testing, CI and deployment
|
||||
======================================
|
||||
|
||||
xdist_ (external) loop on failing tests, distribute test runs to CPUs and hosts.
|
||||
|
||||
pastebin_ submit failure or test session information to a pastebin service.
|
||||
|
||||
junitxml_ logging of test results in JUnit-XML format, for use with Hudson
|
||||
|
||||
resultlog_ non-xml machine-readable logging of test results.
|
||||
|
||||
genscript_ generate standalone test script to be distributed along with an application.
|
||||
|
||||
|
||||
testing domains and conventions codecheckers
|
||||
============================================
|
||||
|
||||
oejskit_ (external) run javascript tests in real life browsers
|
||||
|
||||
django_ (external) for testing django applications
|
||||
|
||||
unittest_ automatically discover and run traditional "unittest.py" style tests.
|
||||
|
||||
nose_ nose-compatibility plugin: allow to run nose test suites natively.
|
||||
|
||||
doctest_ collect and execute doctests from modules and test files.
|
||||
|
||||
restdoc_ perform ReST syntax, local and remote reference tests on .rst/.txt files.
|
||||
|
||||
|
||||
internal, debugging, help functionality
|
||||
=======================================
|
||||
|
||||
helpconfig_ provide version info, conftest/environment config names.
|
||||
|
||||
terminal_ Implements terminal reporting of the full testing process.
|
||||
|
||||
hooklog_ log invocations of extension hooks to a file.
|
||||
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,45 +0,0 @@
|
||||
.. _`helpconfig`: helpconfig.html
|
||||
.. _`pytest_recwarn.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_recwarn.py
|
||||
.. _`unittest`: unittest.html
|
||||
.. _`pytest_monkeypatch.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_monkeypatch.py
|
||||
.. _`pastebin`: pastebin.html
|
||||
.. _`skipping`: skipping.html
|
||||
.. _`plugins`: index.html
|
||||
.. _`mark`: mark.html
|
||||
.. _`tmpdir`: tmpdir.html
|
||||
.. _`pytest_doctest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_doctest.py
|
||||
.. _`capture`: capture.html
|
||||
.. _`pytest_nose.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_nose.py
|
||||
.. _`pytest_restdoc.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_restdoc.py
|
||||
.. _`restdoc`: restdoc.html
|
||||
.. _`xdist`: xdist.html
|
||||
.. _`pytest_pastebin.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_pastebin.py
|
||||
.. _`pytest_tmpdir.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_tmpdir.py
|
||||
.. _`terminal`: terminal.html
|
||||
.. _`pytest_hooklog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_hooklog.py
|
||||
.. _`capturelog`: capturelog.html
|
||||
.. _`junitxml`: junitxml.html
|
||||
.. _`pytest_skipping.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_skipping.py
|
||||
.. _`checkout the pytest development version`: ../../install.html#checkout
|
||||
.. _`pytest_helpconfig.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_helpconfig.py
|
||||
.. _`oejskit`: oejskit.html
|
||||
.. _`doctest`: doctest.html
|
||||
.. _`pytest_mark.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_mark.py
|
||||
.. _`get in contact`: ../../contact.html
|
||||
.. _`pytest_capture.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_capture.py
|
||||
.. _`figleaf`: figleaf.html
|
||||
.. _`customize`: ../customize.html
|
||||
.. _`hooklog`: hooklog.html
|
||||
.. _`pytest_terminal.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_terminal.py
|
||||
.. _`recwarn`: recwarn.html
|
||||
.. _`pytest_pdb.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_pdb.py
|
||||
.. _`monkeypatch`: monkeypatch.html
|
||||
.. _`coverage`: coverage.html
|
||||
.. _`resultlog`: resultlog.html
|
||||
.. _`cov`: cov.html
|
||||
.. _`pytest_junitxml.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_junitxml.py
|
||||
.. _`django`: django.html
|
||||
.. _`pytest_unittest.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_unittest.py
|
||||
.. _`nose`: nose.html
|
||||
.. _`pytest_resultlog.py`: http://bitbucket.org/hpk42/py-trunk/raw/1.3.4/py/_plugin/pytest_resultlog.py
|
||||
.. _`pdb`: pdb.html
|
||||
@@ -1,56 +0,0 @@
|
||||
|
||||
nose-compatibility plugin: allow to run nose test suites natively.
|
||||
==================================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
This is an experimental plugin for allowing to run tests written
|
||||
in 'nosetests' style with ``pytest``.
|
||||
|
||||
Usage
|
||||
-------------
|
||||
|
||||
type::
|
||||
|
||||
pytest # instead of 'nosetests'
|
||||
|
||||
and you should be able to run nose style tests and at the same
|
||||
time can make full use of pytest's capabilities.
|
||||
|
||||
Supported nose Idioms
|
||||
----------------------
|
||||
|
||||
* setup and teardown at module/class/method level
|
||||
* SkipTest exceptions and markers
|
||||
* setup/teardown decorators
|
||||
* yield-based tests and their setup
|
||||
* general usage of nose utilities
|
||||
|
||||
Unsupported idioms / issues
|
||||
----------------------------------
|
||||
|
||||
- nose-style doctests are not collected and executed correctly,
|
||||
also fixtures don't work.
|
||||
|
||||
- no nose-configuration is recognized
|
||||
|
||||
If you find other issues or have suggestions please run::
|
||||
|
||||
pytest --pastebin=all
|
||||
|
||||
and send the resulting URL to a ``pytest`` contact channel,
|
||||
at best to the mailing list.
|
||||
|
||||
Start improving this plugin in 30 seconds
|
||||
=========================================
|
||||
|
||||
|
||||
1. Download `pytest_nose.py`_ plugin source code
|
||||
2. put it somewhere as ``pytest_nose.py`` into your import path
|
||||
3. a subsequent ``pytest`` run will use your local version
|
||||
|
||||
Checkout customize_, other plugins_ or `get in contact`_.
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,12 +0,0 @@
|
||||
pytest_oejskit plugin (EXTERNAL)
|
||||
==========================================
|
||||
|
||||
The `oejskit`_ offers a ``pytest`` plugin for running Javascript tests in live browsers. Running inside the browsers comes with some speed cost, on the other hand it means for example the code is tested against the real-word DOM implementations.
|
||||
The approach enables to write integration tests such that the JavaScript code is tested against server-side Python code mocked as necessary. Any server-side framework that can already be exposed through WSGI (or for which a subset of WSGI can be written to accommodate the jskit own needs) can play along.
|
||||
|
||||
For more info and download please visit the `oejskit PyPI`_ page.
|
||||
|
||||
.. _`oejskit`:
|
||||
.. _`oejskit PyPI`: https://pypi.org/project/oejskit/
|
||||
|
||||
.. source link 'http://bitbucket.org/pedronis/js-infrastructure/src/tip/pytest_jstests.py',
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
Implements terminal reporting of the full testing process.
|
||||
==========================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
This is a good source for looking at the various reporting hooks.
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``-v, --verbose``
|
||||
increase verbosity.
|
||||
``-r chars``
|
||||
show extra test summary info as specified by chars (f)ailed, (s)skipped, (x)failed, (X)passed.
|
||||
``-l, --showlocals``
|
||||
show locals in tracebacks (disabled by default).
|
||||
``--tb=style``
|
||||
traceback print mode (long/short/line/no).
|
||||
``--full-trace``
|
||||
don't cut any tracebacks (default is to cut).
|
||||
``--fixtures``
|
||||
show available fixtures, sorted by plugin appearance (fixtures with leading ``_`` are only shown with '-v')
|
||||
|
||||
Start improving this plugin in 30 seconds
|
||||
=========================================
|
||||
|
||||
|
||||
1. Download `pytest_terminal.py`_ plugin source code
|
||||
2. put it somewhere as ``pytest_terminal.py`` into your import path
|
||||
3. a subsequent ``pytest`` run will use your local version
|
||||
|
||||
Checkout customize_, other plugins_ or `get in contact`_.
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,172 +0,0 @@
|
||||
|
||||
loop on failing tests, distribute test runs to CPUs and hosts.
|
||||
==============================================================
|
||||
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
The `pytest-xdist`_ plugin extends ``pytest`` with some unique
|
||||
test execution modes:
|
||||
|
||||
* Looponfail: run your tests repeatedly in a subprocess. After each run
|
||||
``pytest`` waits until a file in your project changes and then re-runs the
|
||||
previously failing tests. This is repeated until all tests pass after which
|
||||
again a full run is performed.
|
||||
|
||||
* Load-balancing: if you have multiple CPUs or hosts you can use
|
||||
those for a combined test run. This allows to speed up
|
||||
development or to use special resources of remote machines.
|
||||
|
||||
* Multi-Platform coverage: you can specify different Python interpreters
|
||||
or different platforms and run tests in parallel on all of them.
|
||||
|
||||
Before running tests remotely, ``pytest`` efficiently synchronizes your
|
||||
program source code to the remote place. All test results
|
||||
are reported back and displayed to your local test session.
|
||||
You may specify different Python versions and interpreters.
|
||||
|
||||
.. _`pytest-xdist`: https://pypi.org/project/pytest-xdist/
|
||||
|
||||
Usage examples
|
||||
---------------------
|
||||
|
||||
Speed up test runs by sending tests to multiple CPUs
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
To send tests to multiple CPUs, type::
|
||||
|
||||
pytest -n NUM
|
||||
|
||||
Especially for longer running tests or tests requiring
|
||||
a lot of IO this can lead to considerable speed ups.
|
||||
|
||||
|
||||
Running tests in a Python subprocess
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
To instantiate a python2.4 sub process and send tests to it, you may type::
|
||||
|
||||
pytest -d --tx popen//python=python2.4
|
||||
|
||||
This will start a subprocess which is run with the "python2.4"
|
||||
Python interpreter, found in your system binary lookup path.
|
||||
|
||||
If you prefix the --tx option value like this::
|
||||
|
||||
--tx 3*popen//python=python2.4
|
||||
|
||||
then three subprocesses would be created and tests
|
||||
will be load-balanced across these three processes.
|
||||
|
||||
|
||||
Sending tests to remote SSH accounts
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Suppose you have a package ``mypkg`` which contains some
|
||||
tests that you can successfully run locally. And you
|
||||
have a ssh-reachable machine ``myhost``. Then
|
||||
you can ad-hoc distribute your tests by typing::
|
||||
|
||||
pytest -d --tx ssh=myhostpopen --rsyncdir mypkg mypkg
|
||||
|
||||
This will synchronize your ``mypkg`` package directory
|
||||
to a remote ssh account and then locally collect tests
|
||||
and send them to remote places for execution.
|
||||
|
||||
You can specify multiple ``--rsyncdir`` directories
|
||||
to be sent to the remote side.
|
||||
|
||||
**NOTE:** For ``pytest`` to collect and send tests correctly
|
||||
you not only need to make sure all code and tests
|
||||
directories are rsynced, but that any test (sub) directory
|
||||
also has an ``__init__.py`` file because internally
|
||||
``pytest`` references tests using their fully qualified python
|
||||
module path. **You will otherwise get strange errors**
|
||||
during setup of the remote side.
|
||||
|
||||
Sending tests to remote Socket Servers
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Download the single-module `socketserver.py`_ Python program
|
||||
and run it like this::
|
||||
|
||||
python socketserver.py
|
||||
|
||||
It will tell you that it starts listening on the default
|
||||
port. You can now on your home machine specify this
|
||||
new socket host with something like this::
|
||||
|
||||
pytest -d --tx socket=192.168.1.102:8888 --rsyncdir mypkg mypkg
|
||||
|
||||
|
||||
.. _`atonce`:
|
||||
|
||||
Running tests on many platforms at once
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The basic command to run tests on multiple platforms is::
|
||||
|
||||
pytest --dist=each --tx=spec1 --tx=spec2
|
||||
|
||||
If you specify a windows host, an OSX host and a Linux
|
||||
environment this command will send each tests to all
|
||||
platforms - and report back failures from all platforms
|
||||
at once. The specifications strings use the `xspec syntax`_.
|
||||
|
||||
.. _`xspec syntax`: http://codespeak.net/execnet/trunk/basics.html#xspec
|
||||
|
||||
.. _`socketserver.py`: http://codespeak.net/svn/py/dist/py/execnet/script/socketserver.py
|
||||
|
||||
.. _`execnet`: http://codespeak.net/execnet
|
||||
|
||||
Specifying test exec environments in a conftest.py
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Instead of specifying command line options, you can
|
||||
put options values in a ``conftest.py`` file like this::
|
||||
|
||||
option_tx = ['ssh=myhost//python=python2.7', 'popen//python=python2.7']
|
||||
option_dist = True
|
||||
|
||||
Any commandline ``--tx`` specifications will add to the list of
|
||||
available execution environments.
|
||||
|
||||
Specifying "rsync" dirs in a conftest.py
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
In your ``mypkg/conftest.py`` you may specify directories to synchronise
|
||||
or to exclude::
|
||||
|
||||
rsyncdirs = ['.', '../plugins']
|
||||
rsyncignore = ['_cache']
|
||||
|
||||
These directory specifications are relative to the directory
|
||||
where the ``conftest.py`` is found.
|
||||
|
||||
command line options
|
||||
--------------------
|
||||
|
||||
|
||||
``-f, --looponfail``
|
||||
run tests in subprocess, wait for modified files and re-run failing test set until all pass.
|
||||
``-n numprocesses``
|
||||
shortcut for '--dist=load --tx=NUM*popen'
|
||||
``--boxed``
|
||||
box each test run in a separate process (unix)
|
||||
``--dist=distmode``
|
||||
set mode for distributing tests to exec environments.
|
||||
|
||||
each: send each test to each available environment.
|
||||
|
||||
load: send each test to one available environment so it is run only once.
|
||||
|
||||
(default) no: run tests inprocess, don't distribute.
|
||||
``--tx=xspec``
|
||||
add a test execution environment. some examples: --tx popen//python=python2.7 --tx socket=192.168.1.102:8888 --tx ssh=user@codespeak.net//chdir=testcache
|
||||
``-d``
|
||||
load-balance tests. shortcut for '--dist=load'
|
||||
``--rsyncdir=dir1``
|
||||
add directory for rsyncing to remote tx nodes.
|
||||
|
||||
.. include:: links.txt
|
||||
@@ -1,17 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content=" 1 ; URL=index.html" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var pageTracker = _gat._getTracker("UA-7597274-3");
|
||||
pageTracker._trackPageview();
|
||||
} catch(err) {}</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,6 +5,76 @@
|
||||
Temporary directories and files
|
||||
================================================
|
||||
|
||||
The ``tmp_path`` fixture
|
||||
------------------------
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
You can use the ``tmp_path`` fixture which will
|
||||
provide a temporary directory unique to the test invocation,
|
||||
created in the `base temporary directory`_.
|
||||
|
||||
``tmp_path`` is a ``pathlib/pathlib2.Path`` object. Here is an example test usage:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# content of test_tmp_path.py
|
||||
import os
|
||||
|
||||
CONTENT = u"content"
|
||||
|
||||
|
||||
def test_create_file(tmp_path):
|
||||
d = tmp_path / "sub"
|
||||
d.mkdir()
|
||||
p = d / "hello.txt"
|
||||
p.write_text(CONTENT)
|
||||
assert p.read_text() == CONTENT
|
||||
assert len(list(tmp_path.iterdir())) == 1
|
||||
assert 0
|
||||
|
||||
Running this would result in a passed test except for the last
|
||||
``assert 0`` line which we use to look at values::
|
||||
|
||||
$ pytest test_tmp_path.py
|
||||
=========================== test session starts ============================
|
||||
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
|
||||
rootdir: $REGENDOC_TMPDIR, inifile:
|
||||
collected 1 item
|
||||
|
||||
test_tmp_path.py F [100%]
|
||||
|
||||
================================= FAILURES =================================
|
||||
_____________________________ test_create_file _____________________________
|
||||
|
||||
tmp_path = PosixPath('PYTEST_TMPDIR/test_create_file0')
|
||||
|
||||
def test_create_file(tmp_path):
|
||||
d = tmp_path / "sub"
|
||||
d.mkdir()
|
||||
p = d / "hello.txt"
|
||||
p.write_text(CONTENT)
|
||||
assert p.read_text() == CONTENT
|
||||
assert len(list(tmp_path.iterdir())) == 1
|
||||
> assert 0
|
||||
E assert 0
|
||||
|
||||
test_tmp_path.py:13: AssertionError
|
||||
========================= 1 failed in 0.12 seconds =========================
|
||||
|
||||
The ``tmp_path_factory`` fixture
|
||||
--------------------------------
|
||||
|
||||
.. versionadded:: 3.9
|
||||
|
||||
|
||||
The ``tmp_path_factory`` is a session-scoped fixture which can be used
|
||||
to create arbitrary temporary directories from any other fixture or test.
|
||||
|
||||
It is intended to replace ``tmpdir_factory``, and returns :class:`pathlib.Path` instances.
|
||||
|
||||
|
||||
The 'tmpdir' fixture
|
||||
--------------------
|
||||
|
||||
|
||||
@@ -22,16 +22,15 @@ Almost all ``unittest`` features are supported:
|
||||
|
||||
* ``@unittest.skip`` style decorators;
|
||||
* ``setUp/tearDown``;
|
||||
* ``setUpClass/tearDownClass()``;
|
||||
* ``setUpClass/tearDownClass``;
|
||||
* ``setUpModule/tearDownModule``;
|
||||
|
||||
.. _`load_tests protocol`: https://docs.python.org/3/library/unittest.html#load-tests-protocol
|
||||
.. _`setUpModule/tearDownModule`: https://docs.python.org/3/library/unittest.html#setupmodule-and-teardownmodule
|
||||
.. _`subtests`: https://docs.python.org/3/library/unittest.html#distinguishing-test-iterations-using-subtests
|
||||
|
||||
Up to this point pytest does not have support for the following features:
|
||||
|
||||
* `load_tests protocol`_;
|
||||
* `setUpModule/tearDownModule`_;
|
||||
* `subtests`_;
|
||||
|
||||
Benefits out of the box
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user