{"id":318324,"date":"2021-02-20T09:00:24","date_gmt":"2021-02-20T09:00:24","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=318324"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=318324","title":{"rendered":"Kotlin. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u0427\u0430\u0441\u0442\u044c 2). Kotest. Deep Diving"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/cj\/zc\/qd\/cjzcqdkrw3ru3nxv04yeo-vbz0g.jpeg\" alt=\"Kotest\"><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 \u043f\u0440\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 <strong>Kotlin<\/strong><br \/>  \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 <strong>Kotest<\/strong> \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044e\u0449\u0438\u043c\u0438 \u0438 \u0443\u0441\u043a\u043e\u0440\u044f\u044e\u0449\u0438\u043c\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0443\u0433\u043b\u0443\u0431\u0438\u043c\u0441\u044f \u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Kotest:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0442\u0435\u0441\u0442\u044b<\/li>\n<li>\u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/li>\n<li>\u0438\u0437\u0443\u0447\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/li>\n<li>\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432<\/li>\n<li>\u043f\u0440\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438 <strong>Flaky<\/strong>-\u0442\u0435\u0441\u0442\u044b<\/li>\n<li>\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <strong>\u0424\u0430\u0431\u0440\u0438\u043a \u0442\u0435\u0441\u0442\u043e\u0432<\/strong><\/li>\n<li>\u0438 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0442\u0435\u043c\u0443 <strong>Property Testing<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/520380\/\">\u0427\u0430\u0441\u0442\u044c 1. Kotest: \u041d\u0430\u0447\u0430\u043b\u043e<\/a><a name=\"habracut\"><\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<h3 id=\"o-sebe\">\u041e \u0441\u0435\u0431\u0435<\/h3>\n<p>  <\/p>\n<p>\u042f \u044f\u0432\u043b\u044f\u044e\u0441\u044c QA \u041b\u0438\u0434\u043e\u043c \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 <a href=\"https:\/\/habr.com\/ru\/company\/nspk\/\">\u041c\u0438\u0440 Plat.Form (\u041d\u0421\u041f\u041a)<\/a>. \u041f\u0440\u043e\u0435\u043a\u0442 \u0437\u0430\u0440\u043e\u0434\u0438\u043b\u0441\u044f \u043e\u043a\u043e\u043b\u043e \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u0438 \u0443\u0436\u0435 \u0432\u044b\u0440\u043e\u0441 \u0434\u043e \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u043a\u043e\u043c\u0430\u043d\u0434, \u0433\u0434\u0435 \u0442\u0440\u0443\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0431\u0449\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043e\u043a\u043e\u043b\u043e 10 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 (SDET), \u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0432 \u043b\u0438\u0446\u0435 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u043e\u0432, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u043e\u0432.<br \/>  \u041d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0439 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0438 E2E \u0434\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0432 <code>master<\/code> \u2014 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0430 30 \u043c\u0438\u043a\u0440\u043e-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u2014 Kafka, \u0432\u043d\u0435\u0448\u043d\u0438\u0439 API \u2014 REST, \u0430 \u0442\u0430\u043a\u0436\u0435 2 \u0444\u0440\u043e\u043d\u0442\u043e\u0432\u044b\u0445 Web \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0430\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 <strong>Kotlin<\/strong>, \u0430 \u0434\u0432\u0438\u0436\u043e\u043a \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d <strong>Kotest<\/strong>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438 \u0432 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u0445 \u0441\u0435\u0440\u0438\u0438 \u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e \u043e \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0414\u0432\u0438\u0436\u043a\u0435 \u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u0445 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <strong>\u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430\/Tutorial<\/strong>. <\/p>\n<p>  <\/p>\n<h3 id=\"motivaciya-i-celi\">\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u0438 \u0446\u0435\u043b\u0438<\/h3>\n<p>  <\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u0435. \u041d\u043e \u0441 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043b-\u0432\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0435\u0438\u0437\u0431\u0435\u0436\u043d\u043e \u0440\u0430\u0441\u0442\u0435\u0442 \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432. <\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c &quot;\u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u044b&quot; \u0438 \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0442\u0435\u0441\u0442\u043e\u0432 \u043b\u0438\u0448\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 QA \u043e\u0431\u044f\u0437\u0430\u043d \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430 \u0438 \u0432\u0441\u0435\u0445 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<br \/>  \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e, \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u0443\u044e \u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043a\u0430\u0440\u043a\u0430\u0441\u0430 \u0438 \u0442\u0435\u0441\u0442\u043e\u0432. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0423\u0436\u0435 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>Spring Core\/Test. Dependencies Injection \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 <\/li>\n<li>Spring Data JPA. \u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0411\u0414<\/li>\n<li>TestContainers. \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 Docker \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c\u0438<\/li>\n<li>Allure. \u041e\u0442\u0447\u0435\u0442\u043d\u043e\u0441\u0442\u044c<\/li>\n<li>Awaitility. \u041e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/li>\n<\/ul>\n<p>  <\/p>\n<h3 id=\"gruppirovka-testov\">\u0413\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<blockquote><p>\u0412 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u0432\u0443\u0445 \u0432\u0438\u0434\u043e\u0432: \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u043a\u043e\u0434\u0435 \u043b\u0438\u0431\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0435 \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u0434\u0430 \u0441\u043e \u0441\u0441\u044b\u043b\u043a\u0430\u043c\u0438 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043c\u0435\u0441\u0442\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430.<br \/>  \u041a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u044b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 \u0441\u043a\u0440\u044b\u0442\u044b \u0441\u043f\u043e\u0439\u043b\u0435\u0440\u043e\u043c.<br \/>  \u0420\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f <strong>Kotest 4.3.2<\/strong><\/p><\/blockquote>\n<p>\u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043d\u0430 \u0441\u0430\u043c\u044b\u0445 \u0440\u0430\u043d\u043d\u0438\u0445 \u0441\u0442\u0430\u0434\u0438\u044f\u0445 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0443 \u0442\u0435\u0441\u0442\u043e\u0432. \u0421\u0430\u043c\u044b\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0432\u044b\u043c\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u0443\u043c:<\/p>\n<p>  <\/p>\n<ol>\n<li>\n<p><strong>\u041f\u043e \u0443\u0440\u043e\u0432\u043d\u044e<\/strong>. \u041c\u043e\u0434\u0443\u043b\u044c\u043d\u044b\u0435 -&gt; \u041d\u0430 \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0438\u0441 (\u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043c\u0438\u043a\u0440\u043e-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432) -&gt; \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 -&gt; E2E<\/p>\n<p>  <\/li>\n<li>\n<p><strong>\u041f\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435<\/strong>. Windows\\Linux\\MacOS | Desktop\\Web\\IOS\\Android<\/p>\n<p>  <\/li>\n<li>\n<p><strong>\u041f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/strong>. Frontend\\Backend \u0412 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f: \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f\\\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\\\u041e\u0442\u0447\u0435\u0442\u043d\u043e\u0441\u0442\u044c&#8230;<\/p>\n<p>  <\/li>\n<li>\n<p><strong>\u041f\u043e \u0440\u0435\u043b\u0438\u0437\u0430\u043c<\/strong>. Sprint-1\\Sprint-2 1.0.0\\2.0.0<\/p>\n<p>  <\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0432 <strong>Kotest<\/strong><\/p>\n<p>  <\/p>\n<h4 id=\"tegi\">\u0422\u0435\u0433\u0438<\/h4>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0435\u0433\u0438 \u2014 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043a\u043b\u0430\u0441\u0441\u0430 <code>abstract class io.kotest.core.Tag<\/code>. \u0415\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u043a:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>Tag<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043c\u0435\u043d\u0438 \u043c\u0435\u0442\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e <code>simpleName<\/code> \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0449\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>name<\/code>.<\/li>\n<li>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>io.kotest.core.NamedTag<\/code>, \u0433\u0434\u0435 \u0438\u043c\u044f \u043c\u0435\u0442\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435.<\/li>\n<li>\u0441\u043e\u0437\u0434\u0430\u0442\u044c <code>String<\/code> \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@io.kotest.core.annotation.Tags<\/code>, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 <strong>Kotest<\/strong> \u044d\u0442\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u043b\u0430 \u0442\u0438\u043f <code>KClass&lt;T&gt;<\/code> \u043a\u043b\u0430\u0441\u0441\u0430 \u0442\u0435\u0433\u043e\u0432, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 <code>String<\/code> \u0438\u043c\u044f \u0442\u0435\u0433\u0430.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u0433\u043e\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">\/**  * TAG for annotation @Tag only.  *\/ const val LINUX_TAG = &quot;Linux&quot;  \/**  * Name will be class simple name=Windows  *\/ object Windows : Tag()  \/**  * Override name to Linux.  *\/ object LinuxTag : Tag() {     override val name: String = LINUX_TAG }  \/**  * Create [NamedTag] object with name by constructor.  * Substitute deprecated [io.kotest.core.StringTag]  *\/ val regressTag = NamedTag(&quot;regress&quot;)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0435\u0433 \u043a \u0442\u0435\u0441\u0442\u0443 \u043c\u043e\u0436\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0447\u0435\u0440\u0435\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@Tags<\/code> \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/li>\n<li>extension \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>String.config<\/code> \u0432 \u0442\u0435\u0441\u0442\u0435 \u0438\u043b\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u0442\u0435\u0441\u0442\u0430<\/li>\n<li>\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043c\u0435\u0442\u043e\u0434 <code>tags(): Set&lt;Tag&gt;<\/code> \u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/li>\n<\/ul>\n<p>  <\/p>\n<blockquote><p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u044f \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e, \u0442.\u043a. \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c\u0443 \u0434\u0432\u0438\u0436\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0433\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 <code>Spec<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c <code>init<\/code> \u0431\u043b\u043e\u043a, \u0430 \u0435\u0449\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <em>Dependency injection<\/em> \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435.<\/p><\/blockquote>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441 2-\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">@Tags(LINUX_TAG) \/\/ \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f class LinuxSpec : FreeSpec() {     init {         &quot;1-Test for Linux&quot; { }                                         \/* \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0430 String.config *\/         &quot;2-Test for Linux and Regress only&quot;.config(tags = setOf(regressTag)) { }     } }  class WindowsSpec : FreeSpec() {     \/** Override tags method *\/     override fun tags(): Set&lt;Tag&gt; = setOf(Windows) \/\/ \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430      init {         &quot;Test for Windows&quot; { }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0434\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u0433\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>-Dkotest.tags=&lt;\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e \u0442\u0435\u0433\u0430\u043c&gt;<\/code>.<br \/>  \u0412 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432: <code>(<\/code>, <code>)<\/code>, <code>|<\/code>, <code>&amp;<\/code><\/p>\n<p>  <\/p>\n<blockquote><p>\u0422\u0435\u0433\u0438 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b \u043a \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443<\/p><\/blockquote>\n<p>\u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 \u0432\u0438\u0434\u0435 <code>Gradle task<\/code><\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0431\u043e\u0440 Gradle Tasks \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0433\u0440\u0443\u043f\u043f \u0442\u0435\u0441\u0442\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">\/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0432 Gradle \u0444\u0438\u043b\u044c\u0442\u0440 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e \u043f\u0430\u043a\u0435\u0442\u0430\u043c \u0431\u0435\u0437 \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0433\u043e\u0432 task gradleBuildInFilterTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     systemProperties = System.properties     filter { includeTestsMatching(&quot;ru.iopump.qa.sample.tag.*&quot;) } }  \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442 \u0441 \u0442\u0435\u0433\u0430\u043c\u0438 regress (\u0432 \u0442\u0435\u0441\u0442\u0435) \u0438 Linux (\u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438) \u0432 LinuxSpec task linuxWithRegressOnlyTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     systemProperties = System.properties + [&quot;kotest.tags&quot;: &quot;Linux &amp; regress&quot;] }  \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c 2 \u0442\u0435\u0441\u0442\u0430 \u0441 \u0442\u0435\u0433\u043e\u043c Linux (\u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438) \u0432 LinuxSpec task linuxAllTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     systemProperties = System.properties + [&quot;kotest.tags&quot;: &quot;Linux&quot;] }  \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u0437 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u044b \u0441 \u0442\u0435\u0433\u043e\u043c Linux, \u0430 \u0442\u0430\u043a\u0436\u0435 Windows. \u0422\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f 0 \u0442\u0435\u0441\u0442\u043e\u0432  task noTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     systemProperties = System.properties + [&quot;kotest.tags&quot;: &quot;!Linux &amp; !Windows&quot;] }  \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0442\u0435\u0433 Linux \u043b\u0438\u0431\u043e Windows. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b task linuxAndWindowsTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     systemProperties = System.properties + [&quot;kotest.tags&quot;: &quot;Linux | Windows&quot;] }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 2 \u043c\u043e\u043c\u0435\u043d\u0442\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li>Kotest \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Junit5 Runner, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0435\u043a\u043b\u0430\u0440\u0438\u0440\u043e\u0432\u0430\u043d <strong><code>useJUnitPlatform()<\/code><\/strong><\/li>\n<li>Gradle <strong>\u043d\u0435<\/strong> \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0442\u0435\u0441\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c <code>systemProperties = System.properties<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<h4 id=\"uslovnyy-zapusk\">\u0423\u0441\u043b\u043e\u0432\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a<\/h4>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\/\u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u0432\u0443\u043c\u044f \u043f\u0443\u0442\u044f\u043c\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@io.kotest.core.annotation.EnabledIf<\/code> \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>EnabledCondition<\/code><\/li>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0435\u0441\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 <code>String.config(enabledIf = (TestCase) -&gt; Boolean)<\/code><br \/>  \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440:<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"kotlin\">\/** [io.kotest.core.annotation.EnabledIf] annotation with [io.kotest.core.annotation.EnabledCondition] *\/ @EnabledIf(OnCICondition::class) \/\/ \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0441 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 class CIOnlySpec : FreeSpec() {     init {                             \/* \u041b\u043e\u0433\u0438\u043a\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0442\u0435\u0441\u0442\u0430 *\/         &quot;Test for Jenkins&quot;.config(enabledIf = jenkinsTestCase) { }     } }  \/** typealias EnabledIf = (TestCase) -&gt; Boolean *\/ val jenkinsTestCase: io.kotest.core.test.EnabledIf = { testCase: TestCase -&gt; testCase.displayName.contains(&quot;Jenkins&quot;) }  \/** Separate class implementation [io.kotest.core.annotation.EnabledCondition] *\/ class OnCICondition : EnabledCondition {     override fun enabled(specKlass: KClass&lt;out Spec&gt;) = System.getProperty(&quot;CI&quot;) == &quot;true&quot; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u0435\u0441\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f, \u0435\u0441\u043b\u0438:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u0421\u0440\u0435\u0434\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>CI=true<\/code><\/li>\n<li>\u0412 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u043c \u0438\u043c\u0435\u043d\u0438 <code>TestCase<\/code> \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 <code>Jenkins<\/code><\/li>\n<\/ol>\n<p>  <\/p>\n<blockquote><p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439.<br \/>  \u0415\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043d\u043e \u043c\u0435\u043d\u0435\u0435 \u0433\u0438\u0431\u043a\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0447\u0435\u0440\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>enabled<\/code>.<br \/>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: <code>&quot;My test&quot;.config(enabled = System.getProperty(&quot;CI&quot;) == &quot;true&quot;) { }<\/code><\/p><\/blockquote>\n<p>  <\/p>\n<h3 id=\"posledovatelnost-vypolneniya\">\u041f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<h4 id=\"uroven-specifikacii\">\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/h4>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 JVM. \u042d\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u043d\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u043d\u044b\u0439. \u0415\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0443\u0440\u043e\u0432\u043d\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f enum <code>io.kotest.core.spec.SpecExecutionOrder<\/code><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">object ProjectConfig : AbstractProjectConfig() {     override val specExecutionOrder = SpecExecutionOrder.Annotated }<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><code>SpecExecutionOrder.Undefined<\/code>. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435.<\/li>\n<li><code>SpecExecutionOrder.Lexicographic<\/code>. \u0412 \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438\u043c\u0435\u043d \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/li>\n<li><code>SpecExecutionOrder.Random<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/li>\n<li><code>SpecExecutionOrder.Annotated<\/code>. \u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 <code>@Order<\/code> \u043d\u0430\u0434 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0441 \u043d\u043e\u043c\u0435\u0440\u043d\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c. \u041c\u0435\u043d\u044c\u0448\u0435 \u043d\u043e\u043c\u0435\u0440 \u2014 \u0440\u0430\u043d\u044c\u0448\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. \u041d\u0435 \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 <code>Undefined<\/code><\/li>\n<li><code>SpecExecutionOrder.FailureFirst<\/code>. \u041d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0443\u043f\u0430\u0432\u0448\u0438\u0435 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u043e\u0433\u043e\u043d\u0435 \u0442\u0435\u0441\u0442\u044b, \u0430 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 <code>Lexicographic<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f <code>FailureFirst<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 <code>.\/.kotest\/spec_failures<\/code> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">object ProjectConfig : AbstractProjectConfig() {     override val specExecutionOrder = SpecExecutionOrder.FailureFirst      \/**      * Save execution results to file for [SpecExecutionOrder.FailureFirst] strategy.      * File location: [io.kotest.core.config.Configuration.specFailureFilePath] = &quot;.\/.kotest\/spec_failures&quot;      *\/     override val writeSpecFailureFile = true }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438 <code>Annotated<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">object ProjectConfig : AbstractProjectConfig() {     override val specExecutionOrder = SpecExecutionOrder.Annotated }  @Order(Int.MIN_VALUE) \/\/ \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0435 class FirstSpec : FreeSpec() {     init {         &quot;FirstSpec-Test&quot; { }     } }  @Order(Int.MIN_VALUE + 1) \/\/ \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0435 class SecondSpec : FreeSpec() {     init {         &quot;SecondSpec-Test&quot; { }     } }  @Order(Int.MAX_VALUE) \/\/ \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0435 class LastSpec : FreeSpec() {     init {         &quot;LastSpec-Test&quot; { }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0440\u044f\u0434\u043e\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439: <code>FirstSpec<\/code> -&gt; <code>SecondSpec<\/code> -&gt; <code>LastSpec<\/code>. \u0427\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 <code>@Order<\/code> \u0442\u0435\u043c <strong>\u043f\u043e\u0437\u0436\u0435<\/strong> \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<h4 id=\"uroven-testov\">\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0435\u0441\u0442\u043e\u0432<\/h4>\n<p>  <\/p>\n<p>\u0412\u044b\u0448\u0435 \u0431\u044b\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 (\u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432). \u041d\u043e \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<br \/>  \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043a\u043e\u0434\u0435 <code>TestCaseOrder.Sequential<\/code> \u0438 \u044d\u0442\u043e \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442. \u041e\u0434\u043d\u0430\u043a\u043e \u0438 \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0441\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">object ProjectConfig : AbstractProjectConfig() {     override val testCaseOrder: TestCaseOrder = TestCaseOrder.Random }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>testCaseOrder<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class TestOrderingSpec : FreeSpec() {     override fun testCaseOrder(): TestCaseOrder = TestCaseOrder.Lexicographic }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"parallelnost\">\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/h3>\n<p>  <\/p>\n<p>\u041e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0430\u044f \u0438 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0442\u0435\u043c\u0430, \u043a\u0430\u043a \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0430\u043a \u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<br \/>  \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043a\u043d\u0438\u0433\u043e\u0439 <code>Java Concurrency in Practice<\/code> \u2014 \u043e\u043d\u0430 \u043a\u0430\u043a \u0440\u0430\u0437 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435. <\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043e\u0439 \u0434\u043b\u044f \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441\u043b\u0443\u0436\u0438\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0442\u0435\u0441\u0442\u0430 \u0431\u044b\u0442\u044c \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. <\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0448\u043b\u0430 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430,- \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430, \u043b\u0438\u0431\u043e \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u044e, \u0447\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u043c\u0438 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u0438\u0437\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0441\u0442\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432<\/li>\n<li>\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0441\u0442<\/li>\n<li>\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0443 \u0441\u0430\u043c\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432<\/li>\n<li>\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u0441\u0442\u0430\u043c\u0438<\/li>\n<li>\u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0442\u0435\u0441\u0442\u0430\u043c\u0438<\/li>\n<li>\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438\u043b\u0438 \u0442\u0435\u0441\u0442\u043e\u0432<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438\u043b\u0438 \u0441\u0435\u0441\u0441\u0438\u0438, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u044d\u0442\u043e, \u043e\u0434\u043d\u0430\u043a\u043e 100% \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0434\u0430\u0441\u0442.<br \/>  \u0422\u0435\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432 \u043e\u0431\u0445\u043e\u0434 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0433\u043e API (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0447\u0442\u043e-\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0411\u0414 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e), \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u0440\u0443\u0448\u0438\u0442\u044c \u0438\u0437\u043e\u043b\u044f\u0446\u0438\u044e.<\/p>\n<p>  <\/p>\n<p><strong>Kotest<\/strong> \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/p>\n<p>  <\/p>\n<h4 id=\"uroven-testov-1\">\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0435\u0441\u0442\u043e\u0432<\/h4>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043a\u043e\u043b-\u0432\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0432 \u043c\u0435\u0442\u043e\u0434 <code>fun threads()<\/code><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441 2-\u043c\u044f \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0438 2-\u043c\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">class OneParallelOnTestLevelSpec : FreeSpec() {     private companion object {         private val log = LoggerFactory.getLogger(OneParallelOnTestLevelSpec::class.java)     }      override fun threads(): Int = 2      init {         &quot;parallel on test level 1&quot; {             log.info(&quot;test 1 started&quot;)             delay(500)             log.info(&quot;test 1 finished&quot;)         }          &quot;parallel on test level 2&quot; {             log.info(&quot;test 2 started&quot;)             delay(1000)             log.info(&quot;test 2 finished&quot;)         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e gradle \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">task parallelismTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     filter { includeTestsMatching(&quot;ru.iopump.qa.sample.parallelism.OneParallelOnTestLevelSpec&quot;) } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u0435\u043c \u0432\u044b\u0432\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">21:15:44:979 OneParallelOnTestLevelSpec - test 2 started 21:15:44:979 OneParallelOnTestLevelSpec - test 1 started 21:15:45:490 OneParallelOnTestLevelSpec - test 1 finished 21:15:45:990 OneParallelOnTestLevelSpec - test 2 finished<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e \u043b\u043e\u0433\u0443 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e <code>test 1<\/code> \u0438 <code>test 2<\/code> \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0432 <code>21:15:44:979<\/code> \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438\u0441\u044c:<br \/>  \u043f\u0435\u0440\u0432\u044b\u0439 \u0432 <code>21:15:45:490<\/code>, \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 500\u043c\u0441, \u2014 \u0432\u0441\u0435 \u043f\u043e-\u043f\u043b\u0430\u043d\u0443.<\/p>\n<p>  <\/p>\n<h4 id=\"uroven-specifikacii-1\">\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/h4>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043e \u0438\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">object ProjectConfig : AbstractProjectConfig() {     override val parallelism: Int = 3 }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041b\u0438\u0431\u043e \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>-Dkotest.framework.parallelism=3<\/code> \u0438\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 \u0437\u0430\u0434\u0430\u0447\u0435 gradle:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">task parallelismTest(type: Test) {     group &quot;test&quot;     useJUnitPlatform()     doFirst { systemProperties = System.properties + [&quot;kotest.framework.parallelism&quot;: 3] }     filter { includeTestsMatching(&quot;ru.iopump.qa.sample.parallelism.*&quot;) } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043e\u0434\u043d\u0443 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430 <code>OneParallelOnTestLevelSpec<\/code> \u0438 2 \u043d\u043e\u0432\u044b\u0435, \u0433\u0434\u0435 \u0441\u0430\u043c\u0438 \u0442\u0435\u0441\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0415\u0449\u0435 2 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">class TwoParallelSpec : FreeSpec() {     private companion object {         private val log = LoggerFactory.getLogger(TwoParallelSpec::class.java)     }      init {         &quot;sequential test 1&quot; {             log.info(&quot;test 1 started&quot;)             delay(1000)             log.info(&quot;test 1 finished&quot;)         }          &quot;sequential test 2&quot; {             log.info(&quot;test 2 started&quot;)             delay(1000)             log.info(&quot;test 2 finished&quot;)         }     } }  class ThreeParallelSpec : FreeSpec() {     private companion object {         private val log = LoggerFactory.getLogger(ThreeParallelSpec::class.java)     }      init {         &quot;sequential test 1&quot; {             log.info(&quot;test 1 started&quot;)             delay(1000)             log.info(&quot;test 1 finished&quot;)         }          &quot;sequential test 2&quot; {             log.info(&quot;test 2 started&quot;)             delay(1000)             log.info(&quot;test 2 finished&quot;)         }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 3 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0435\u0441\u0442\u044b \u0432 <code>OneParallelOnTestLevelSpec<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0441\u0432\u043e\u0438\u0445 2-\u0443\u0445 \u043f\u043e\u0442\u043e\u043a\u0430\u0445:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">21:44:16:216 [kotest-engine-1] CustomKotestExtension - [BEFORE] prepareSpec class ru.iopump.qa.sample.parallelism.ThreeParallelSpec 21:44:16:216 [kotest-engine-2] CustomKotestExtension - [BEFORE] prepareSpec class ru.iopump.qa.sample.parallelism.TwoParallelSpec 21:44:16:216 [kotest-engine-0] CustomKotestExtension - [BEFORE] prepareSpec class ru.iopump.qa.sample.parallelism.OneParallelOnTestLevelSpec 21:44:18:448 [SpecRunner-3] ThreeParallelSpec - test 2 started 21:44:18:448 [SpecRunner-6] OneParallelOnTestLevelSpec - test 1 started 21:44:18:448 [SpecRunner-5] TwoParallelSpec - test 1 started 21:44:18:448 [SpecRunner-4] OneParallelOnTestLevelSpec - test 2 started 21:44:18:959 [SpecRunner-6] OneParallelOnTestLevelSpec - test 1 finished 21:44:19:465 [SpecRunner-5] TwoParallelSpec - test 1 finished 21:44:19:465 [SpecRunner-3] ThreeParallelSpec - test 2 finished 21:44:19:465 [SpecRunner-4] OneParallelOnTestLevelSpec - test 2 finished 21:44:19:471 [SpecRunner-5] TwoParallelSpec - test 2 started 21:44:19:472 [SpecRunner-3] ThreeParallelSpec - test 1 started 21:44:20:484 [SpecRunner-3] ThreeParallelSpec - test 1 finished 21:44:20:484 [SpecRunner-5] TwoParallelSpec - test 2 finished<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e \u043b\u043e\u0433\u0443 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 3 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0448\u043b\u0438 \u0437\u0430 2 \u0441\u0435\u043a \u2014 \u044d\u0442\u043e \u0441\u0443\u043c\u043c\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0445 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 \u0432\u044b\u0448\u0435, \u0442\u0435\u0441\u0442\u044b \u0438\u0437 <code>OneParallelOnTestLevelSpec<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438\u0441\u044c \u0435\u0449\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435.<br \/>  \u0412 \u0432\u044b\u0432\u043e\u0434\u0435 \u044f \u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043f\u0435\u0440\u0432\u044b\u0435 \u0442\u0440\u0438 \u0441\u0442\u0440\u043e\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u0430 \u043f\u043e\u0442\u043e\u043a\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u0443\u043b \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439 <code>NamedThreadFactory(&quot;kotest-engine-%d&quot;)<\/code><\/li>\n<li>\u043f\u0443\u043b \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 <code>NamedThreadFactory(&quot;SpecRunner-%d&quot;)<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u044d\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>Executors.newFixedThreadPool<\/code> \u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0432 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f, \u0442.\u043a. <code>suspend<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>runBlocking<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">executor.submit {     runBlocking {         run(testCase)     } }<\/code><\/pre>\n<p>  <\/p>\n<blockquote><p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 <code>io.kotest.engine.KotestEngine.submitBatch<\/code> \u0438 <code>io.kotest.engine.spec.SpecRunner.runParallel<\/code><\/p><\/blockquote>\n<p>  <\/p>\n<h4 id=\"isklyuchenie-iz-parallelnogo-zapuska\">\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/h4>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <code>@DoNotParallelize<\/code>.<br \/>  \u0414\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e.<\/p>\n<p>  <\/p>\n<h3 id=\"taymauty\">\u0422\u0430\u0439\u043c\u0430\u0443\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>\u0418\u043c\u0435\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u043c\u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430:<\/p>\n<p>  <\/p>\n<blockquote><p>\u0414\u043b\u044f \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u0434\u0435 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043a\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 <code>\/*\u043d\u043e\u043c\u0435\u0440*\/<\/code> \u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e \u043a\u0430\u0436\u0434\u0443\u044e \u0432 \u0432\u0438\u0434\u0435: <code>\u043d\u043e\u043c\u0435\u0440<\/code> &#8212;<\/p><\/blockquote>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">@ExperimentalTime class TimeoutSpec : FreeSpec() {     private companion object {         private val log = LoggerFactory.getLogger(TimeoutSpec::class.java)     }      \/*1*\/override fun timeout(): Long = 2000 \/\/ Spec Level timeout for each TestCase not total     \/*2*\/override fun invocationTimeout(): Long =         2000 \/\/ Spec Level invocation timeout for each TestCase invocation not total      init {         \/*3*\/timeout = 1500 \/\/ Spec Level timeout for each TestCase not total         \/*4*\/invocationTimeout = 1500 \/\/ Spec Level invocation timeout for each TestCase invocation not total         &quot;should be invoked 2 times and will be successful at all&quot;.config(             \/*5*\/invocations = 2,             \/*6*\/invocationTimeout = 550.milliseconds,             \/*7*\/timeout = 1100.milliseconds         ) {             log.info(&quot;test 1&quot;)             delay(500)         }          &quot;should be invoked 2 times and every will fail by invocationTimeout&quot;.config(             invocations = 2,             invocationTimeout = 400.milliseconds,             timeout = 1050.milliseconds         ) {             log.info(&quot;test 2&quot;)             delay(500)         }          &quot;should be invoked 2 times and last will fail by total timeout&quot;.config(             invocations = 2,             invocationTimeout = 525.milliseconds,             timeout = 1000.milliseconds         ) {             log.info(&quot;test 3&quot;)             delay(500)         }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<blockquote><p>\u0410\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 \u043d\u0430 \u0432\u0441\u044e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0435\u0442. \u0412\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u0435\u0441\u0442.<\/p><\/blockquote>\n<p><code>5<\/code> \u2014 <code>invocations = 2<\/code> \u0412 <strong>Kotest<\/strong> \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0439 \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c.<br \/>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0442\u0435\u0441\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c, \u0442\u043e \u0442\u0435\u0441\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c. \u041d\u0435 \u043f\u0443\u0442\u0430\u0439\u0442\u0435 \u0441 <em>fluky<\/em> \u2014 \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f.<\/p>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 <code>override fun timeout(): Long = 2000<\/code> \u0427\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0442\u0435\u0441\u0442 \u0432 \u043c\u0441.<\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 <code>override fun invocationTimeout(): Long = 2000<\/code> \u0427\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 \u0442\u0435\u0441\u0442\u0430 \u0432 \u043c\u0441 (\u0441\u043c <code>5<\/code>).<\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 <code>timeout = 1500<\/code> \u0427\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0442\u0435\u0441\u0442 \u0432 \u043c\u0441 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c <code>1<\/code><\/p>\n<p>  <\/p>\n<p><code>4<\/code> \u2014 <code>invocationTimeout = 1500<\/code> \u0427\u0435\u0440\u0435\u0437 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 \u0442\u0435\u0441\u0442\u0430 \u0432 \u043c\u0441 \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c <code>2<\/code> (\u0441\u043c <code>5<\/code>).<\/p>\n<p>  <\/p>\n<p><code>6<\/code> \u2014 <code>invocationTimeout = 550.milliseconds<\/code> \u0427\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0430. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u0442\u0435\u0441\u0442 \u0432 <code>kotlin.time.Duration<\/code> \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c <code>3<\/code>.<\/p>\n<p>  <\/p>\n<p><code>7<\/code> \u2014 <code>timeout = 1100.milliseconds<\/code> \u0427\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0430. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043d\u0430 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 \u0442\u0435\u0441\u0442\u0430 \u0432 <code>kotlin.time.Duration<\/code> \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c <code>4<\/code> (\u0441\u043c <code>5<\/code>).<\/p>\n<p>  <\/p>\n<blockquote><p><code>kotlin.time.Duration<\/code> \u0438\u043c\u0435\u0435\u0442 \u0441\u0442\u0430\u0442\u0443\u0441 <code>Experimental<\/code> \u0438 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 <code>@ExperimentalTime<\/code> \u043d\u0430\u0434 \u043a\u043b\u0430\u0441\u0441\u043e\u043c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/p><\/blockquote>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 <code>TimeoutSpec<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">08:23:35:183 TimeoutSpec - test 1 08:23:35:698 TimeoutSpec - test 1 08:23:36:212 CustomKotestExtension - [AFTER] afterTest. Test case duration: 1047 ms  08:23:36:217 TimeoutSpec - test 2 Test did not complete within 400ms TimeoutException(duration=400)  08:23:36:625 TimeoutSpec - test 3 08:23:37:141 TimeoutSpec - test 3 Test did not complete within 1000ms TimeoutException(duration=1000)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0442\u0435\u0441\u0442 \u043f\u0440\u043e\u0448\u0435\u043b \u0443\u0441\u043f\u0435\u0448\u043d\u043e 2 \u0440\u0430\u0437\u0430, \u043a\u0430\u0436\u0434\u043e\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0443\u043c\u0435\u0441\u0442\u0438\u043b\u043e\u0441\u044c <code>invocationTimeout<\/code> \u0438 \u0432\u0435\u0441\u044c \u0442\u0435\u0441\u0442 \u0432 <code>timeout<\/code><br \/>  \u0412\u0442\u043e\u0440\u043e\u0439 \u0442\u0435\u0441\u0442 \u0443\u043f\u0430\u043b \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0438 \u043d\u0435 \u0441\u0442\u0430\u043b \u0434\u0430\u043b\u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e <code>invocationTimeout<\/code> \u2014 <code>TimeoutException(duration=400)<\/code><br \/>  \u0422\u0440\u0435\u0442\u0438\u0439 \u0442\u0435\u0441\u0442 \u0443\u043f\u0430\u043b \u043d\u0430 \u0432\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 <code>timeout<\/code> \u2014 <code>TimeoutException(duration=1000)<\/code><\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">@ExperimentalTime object ProjectConfig : AbstractProjectConfig() {     \/** -Dkotest.framework.timeout in ms *\/     override val timeout = 60.seconds      \/** -Dkotest.framework.invocation.timeout in ms *\/     override val invocationTimeout: Long = 10_000 }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"vstroennye-ozhidaniya\">\u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043d\u0430\u0448\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0435 \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 E2E. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f <strong>\u0432\u0441\u0435\u0445<\/strong> \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435. \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u043f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 HTTP \u043e\u0442\u0432\u0435\u0442\u0430 (\u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 HTTP \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0430\u0439\u043c\u0430\u0443\u0442)<\/li>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0435<\/li>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f\/\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414<\/li>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438<\/li>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0440\u0435\u0430\u043a\u0446\u0438\u0438 UI (\u0434\u043b\u044f Web \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432 Selenide)<\/li>\n<li>\u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u043f\u0438\u0441\u044c\u043c\u0430 \u043d\u0430 SMTP \u0441\u0435\u0440\u0432\u0435\u0440\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<blockquote><p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0436\u0434\u0430\u0442\u044c \u0432 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0435 \u0438\u043b\u0438 \u0432 \u0411\u0414, \u2014 \u043e\u0442\u0432\u0435\u0447\u0443 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e<\/p><\/blockquote>\n<p>\u0415\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0442\u043e\u043d\u043a\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0439: <a href=\"https:\/\/github.com\/awaitility\/awaitility\">Awaitility<\/a> \u2014 \u043e \u043d\u0435\u0439 \u043f\u043e\u0439\u0434\u0435\u0442 \u0440\u0435\u0447\u044c \u0432 \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445. \u041d\u043e <strong>Kotest<\/strong> \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0439.<br \/>  \u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u043a\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437\u0434\u0435\u043b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>Non-deterministic Testing<\/code>.<\/p>\n<p>  <\/p>\n<h4 id=\"eventually\">Eventually<\/h4>\n<p>  <\/p>\n<p>\u041f\u043e\u0434\u043e\u0436\u0434\u0430\u0442\u044c \u043f\u043e\u043a\u0430 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u043f\u0440\u043e\u0439\u0434\u0435\u0442 \u0431\u0435\u0437 \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0442\u043e \u0435\u0441\u0442\u044c \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0445\u0430 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0431\u043b\u043e\u043a \u0435\u0449\u0435 \u0440\u0430\u0437.<br \/>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 <code>io.kotest.assertions.timing<\/code>: <code>suspend fun &lt;T, E : Throwable&gt; eventually(duration: Duration, poll: Duration, exceptionClass: KClass&lt;E&gt;, f: suspend () -&gt; T): T<\/code><\/p>\n<p>  <\/p>\n<p><code>f<\/code> \u2014 \u044d\u0442\u043e \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043b\u0438\u0431\u043e \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 <code>duration<\/code>.<br \/>  <code>poll<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f.<br \/>  <code>exceptionClass<\/code> \u2014 \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0435\u0449\u0435 \u0440\u0430\u0437.<br \/>  \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 <code>IllegalStateException<\/code>, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u0440\u0430\u0437, \u043d\u043e \u0435\u0441\u043b\u0438, \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433\u043e\u0439, \u0442\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043a\u043e\u0434 \u0442\u043e\u0447\u043d\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c\u0441\u044f \u0438 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u043e\u0434 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u0442\u043e\u0433\u0434\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>IllegalStateException::class<\/code>.<\/p>\n<p>  <\/p>\n<h4 id=\"continually\">Continually<\/h4>\n<p>  <\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043b\u0438\u0431\u043e \u043f\u043e\u043a\u0430 \u043a\u043e\u0434 \u043d\u0435 \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442 \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.<br \/>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 <code>io.kotest.assertions.timing<\/code>: <code>suspend fun &lt;T&gt; continually(duration: Duration, poll: Duration, f: suspend () -&gt; T): T?<\/code><\/p>\n<p>  <\/p>\n<p><code>f<\/code> \u2014 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0432 \u0446\u0438\u043a\u043b\u0435 \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 <code>duration<\/code> \u043b\u0438\u0431\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435.<br \/>  <code>poll<\/code> \u2014 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f<\/p>\n<p>  <\/p>\n<h4 id=\"rassmotrim-primer-iz-chetyreh-testov-2-eventually--2-continually\">\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 (2 eventually + 2 continually)<\/h4>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">@ExperimentalTime class WaitSpec : FreeSpec() {     private companion object {         private val log = LoggerFactory.getLogger(WaitSpec::class.java)     }      \/*1*\/     private lateinit var tries: Iterator&lt;Boolean&gt;     private lateinit var counter: AtomicInteger     private val num: Int get() = counter.incrementAndGet()      init {         \/*2*\/         beforeTest {             tries = listOf(true, true, false).iterator()             counter = AtomicInteger()         }          &quot;eventually waiting should be success&quot; {             \/*3*\/eventually(200.milliseconds, 50.milliseconds, IllegalStateException::class) {             log.info(&quot;Try #$num&quot;)             if (tries.next()) \/*4*\/ throw IllegalStateException(&quot;Try #$counter&quot;)         }         }          &quot;eventually waiting should be failed on second try&quot; {             \/*5*\/shouldThrow&lt;AssertionError&gt; {             eventually(\/*6*\/100.milliseconds, 50.milliseconds, IllegalStateException::class) {                 log.info(&quot;Try #$num&quot;)                 if (tries.next()) throw IllegalStateException(&quot;Try #$counter&quot;)             }         }.toString().also(log::error)         }          &quot;continually waiting should be success&quot; - {             \/*7*\/continually(200.milliseconds, 50.milliseconds) {             log.info(&quot;Try #$num&quot;)         }         }          &quot;continually waiting should be failed on third try&quot; {             \/*8*\/shouldThrow&lt;IllegalStateException&gt; {             continually(200.milliseconds, 50.milliseconds) {                 log.info(&quot;Try #$num&quot;)                 if (tries.next()) throw IllegalStateException(&quot;Try #$counter&quot;)             }         }.toString().also(log::error)         }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 \u0411\u043b\u043e\u043a \u0441 \u043f\u043e\u043b\u044f\u043c\u0438 \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0447\u0435\u0442\u0430 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0438\u0437 \u0442\u0440\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432<\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 \u041f\u0435\u0440\u0435\u0434 \u043a\u0430\u0436\u0434\u044b\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u043c \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0438<\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>eventually<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e. \u041e\u0431\u0449\u0438\u0439 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 200 \u043c\u0441, \u043f\u0435\u0440\u0435\u0440\u044b\u0432 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 50 \u043c\u0441, \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <code>IllegalStateException<\/code><\/p>\n<p>  <\/p>\n<p><code>4<\/code> \u2014 \u041f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0435 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0442 <code>IllegalStateException<\/code>, \u0430 3-\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e.<\/p>\n<p>  <\/p>\n<p><code>5<\/code> \u2014 \u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e <code>eventually<\/code> \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u041f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0435 <code>eventually<\/code><br \/>  \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 <code>AssertionError<\/code> \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u0438 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445.<\/p>\n<p>  <\/p>\n<p><code>6<\/code> \u2014 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u0430 100 \u043c\u0441 \u0438 \u043f\u0435\u0440\u0435\u0440\u044b\u0432 \u043c\u0435\u0436\u0434\u0443 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 50 \u043c\u0441, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 2 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u044b\u0439 \u043f\u043e\u043f\u044b\u0442\u043a\u0438, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e<\/p>\n<p>  <\/p>\n<p><code>7<\/code> \u2014 <code>continually<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442 4 \u043f\u043e\u043f\u044b\u0442\u043a\u0438, \u0432\u0441\u0435 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0435 \u0438 \u0441\u0430\u043c\u043e \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0445\u043e\u043c<\/p>\n<p>  <\/p>\n<p><code>8<\/code> \u2014 \u041e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e <code>continually<\/code> \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u041f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0435 <code>continually<\/code><br \/>  \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 \u043a\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438, \u0442\u043e \u0435\u0441\u0442\u044c <code>IllegalStateException<\/code>, \u0447\u0435\u043c \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 <code>eventually<\/code><\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041b\u043e\u0433 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 1 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 21:12:14:796 INFO CustomKotestExtension - [BEFORE] test eventually waiting should be success 21:12:14:812 INFO WaitSpec - Try #1 21:12:14:875 INFO WaitSpec - Try #2 21:12:14:940 INFO WaitSpec - Try #3 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 2 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 21:12:14:940 INFO CustomKotestExtension - [BEFORE] test eventually waiting should be failed on second try 21:12:14:956 INFO WaitSpec - Try #1 21:12:15:018 INFO WaitSpec - Try #2  \/* \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043e\u0448\u0438\u0431\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f *\/ 21:12:15:081 ERROR WaitSpec - java.lang.AssertionError: Eventually block failed after 100ms; attempted 2 time(s); 50.0ms delay between attempts  \/* \u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0432 \u043e\u0448\u0438\u0431\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0435\u0440\u0432\u043e\u0435 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043d\u043e\u0435 \u043a\u043e\u0434\u043e\u043c \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 *\/  The first error was caused by: Try #1 java.lang.IllegalStateException: Try #1 The last error was caused by: Try #2 java.lang.IllegalStateException: Try #2 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 3 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 21:12:15:081 INFO CustomKotestExtension - [BEFORE] test continually waiting should be success 21:12:15:081 INFO WaitSpec - Try #1 21:12:15:159 INFO WaitSpec - Try #2 21:12:15:221 INFO WaitSpec - Try #3 21:12:15:284 INFO WaitSpec - Try #4 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 4 \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ 21:12:15:346 INFO CustomKotestExtension - [BEFORE] test continually waiting should be failed on third try 21:12:15:346 INFO WaitSpec - Try #1 21:12:15:409 INFO WaitSpec - Try #2 21:12:15:469 INFO WaitSpec - Try #3  \/* \u0417\u0434\u0435\u0441\u044c \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0432 continually *\/ 21:12:15:469 ERROR WaitSpec - java.lang.IllegalStateException: Try #3<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h3 id=\"flaky-testy\">Flaky \u0442\u0435\u0441\u0442\u044b<\/h3>\n<p>  <\/p>\n<p>Flaky \u0442\u0435\u0441\u0442\u044b \u2014 \u044d\u0442\u043e \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e. \u041f\u0440\u0438\u0447\u0438\u043d \u044d\u0442\u043e\u043c\u0443 \u043a\u0440\u0430\u0439\u043d\u0435 \u043c\u043d\u043e\u0433\u043e \u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043c\u044b \u0438\u0445 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 CI \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0432\u0441\u044e \u0417\u0430\u0434\u0430\u0447\u0443 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430<\/li>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 Gradle \u0441\u0431\u043e\u0440\u043a\u0438, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043b\u0430\u0433\u0438\u043d <a href=\"https:\/\/github.com\/gradle\/test-retry-gradle-plugin\"><code>test-retry-gradle-plugin<\/code><\/a> \u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433<\/li>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 Gradle \u0441\u0431\u043e\u0440\u043a\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0443\u043f\u0430\u0432\u0448\u0438\u0435 \u0442\u0435\u0441\u0442\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0445 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435<\/li>\n<\/ul>\n<p>  <\/p>\n<blockquote><p>\u0414\u0440\u0443\u0433\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 Java\/Kotlin\/Groovy \u043a\u0440\u043e\u043c\u0435 Gradle \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e<\/p><\/blockquote>\n<p>  <\/p>\n<ul>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0434\u0432\u0438\u0436\u043a\u0430<\/li>\n<li>\u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0431\u043b\u043e\u043a\u043e\u0432 \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u0435 (\u0441\u043c. \u0440\u0430\u0437\u0434\u0435\u043b \u0412\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438 retry)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 <strong>Kotest<\/strong> <code>4.3.2<\/code> \u043d\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432. \u0418 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 Gradle \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c <a href=\"https:\/\/github.com\/gradle\/test-retry-gradle-plugin\"><code>test-retry-gradle-plugin<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430. \u042d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f UI \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0433\u0434\u0430 \u043a\u043b\u0438\u043a \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u043d\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442.<br \/>  \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u0441 <code>Dropdown<\/code> \u0432\u043d\u0438\u0437\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u043e\u0441\u043b\u0435 \u0441\u043a\u0440\u043e\u043b\u043b\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043a\u043b\u0438\u043a, \u0434\u0430\u043b\u0435\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043a\u043b\u0438\u043a \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043f\u0438\u0441\u043a\u0430.<br \/>  \u0422\u0430\u043a \u0432\u043e\u0442, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0424\u0440\u043e\u043d\u0442\u043e\u0432\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0438\u043d\u043e\u0433\u0434\u0430 \u043a\u043b\u0438\u043a \u0434\u043b\u044f \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0440\u0430\u0437 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043a\u043b\u0438\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440 \u0447\u0435\u0440\u0435\u0437 <code>try\/catch<\/code>, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<br \/>  \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>suspend fun &lt;T, E : Throwable&gt; retry(maxRetry: Int, timeout: Duration, delay: Duration = 1.seconds, multiplier: Int = 1, exceptionClass: KClass&lt;E&gt;, f: suspend () -&gt; T):<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">\/\/ using Selenide dropdown.scrollTo() retry(2, 20.seconds, exceptionClass = Throwable::class) {     dropdown.click()     dropdownItems.find(Condition.text(&quot;1&quot;)).apply {         click()         should(Condition.disappear)     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 <code>scrollTo<\/code> \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u0431\u043b\u043e\u043a \u0441 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435\u043c \u0441\u043f\u0438\u0441\u043a\u0430 \u0438 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c 2 \u0440\u0430\u0437\u0430, \u043d\u043e \u043d\u0435 \u0434\u043e\u043b\u044c\u0448\u0435 20 \u0441\u0435\u043a \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044f \u0432\u0441\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f (\u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435).<\/p>\n<p>  <\/p>\n<p>\u0412 <strong>Kotest<\/strong> \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u043f\u0430\u0432\u0448\u0438\u0445 <code>\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439\/\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0442\u0435\u0441\u0442\u0430\/\u0442\u0435\u0441\u0442\u043e\u0432<\/code>.<br \/>  \u0412 <em>3 \u0447\u0430\u0441\u0442\u0438<\/em> \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u0443\u0440\u043e\u0432\u043d\u044f \u0442\u0435\u0441\u0442\u043e\u0432.<br \/>  \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u043c GitHub \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0435 \u0438 \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432 MavenCentral, \u0435\u0441\u043b\u0438 \u043a \u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a Kotest \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 &#8216;\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438&#8217;.<\/p>\n<p>  <\/p>\n<h3 id=\"fabriki-testov\">\u0424\u0430\u0431\u0440\u0438\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0442\u0435\u0441\u0442\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f: \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0411\u0414, \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435. <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d \u0442\u0435\u0441\u0442\u0430 \u0441 \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0432 \u0432\u0438\u0434\u0435 <code>javadoc<\/code>\/<code>kdoc<\/code> \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043c\u0435\u043d\u0435\u043c \u0438 \u043f\u0430\u0440\u043e\u043b\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. <\/p>\n<p>  <\/p>\n<p>\u0412 <strong>Kotest<\/strong> \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>Test Factories<\/code> \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0443\u0441\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0442\u0435\u0441\u0442. <\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u0438 \u043c\u0435\u0442\u043e\u0434\u044b, \u043d\u0438 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u0442\u0435\u0441\u0442\u0430 \u0441 \u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439, \u0447\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0435\u0441\u0442, \u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<blockquote><p>\u042f \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0441\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0447\u0442\u043e <strong>\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f<\/strong> \u0442\u0435\u0441\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u0430 \u043b\u044e\u0431\u043e\u043c\u0443 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0443, \u0438\u043c\u0435\u044e\u0449\u0435\u043c\u0443 \u044d\u043a\u0441\u043f\u0435\u0440\u0442\u0438\u0437\u0443 \u0432 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0442\u0435\u0441\u0442\u0430.<br \/>  \u041f\u043e\u0434 <strong>\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439<\/strong> \u0442\u0435\u0441\u0442\u0430 \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0448\u0430\u0433\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a \u0432 BDD \u0441\u0442\u0438\u043b\u0435. \u0412 <a href=\"https:\/\/habr.com\/ru\/post\/520380\/\">1-\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430<\/a> \u044f \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u043b \u0442\u0435\u043c\u0443 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e.<br \/>  \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e <code>copy\/paste<\/code> \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0442\u0435\u0441\u0442\u0430, <strong>\u043d\u0443\u0436\u043d\u043e<\/strong> \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c.<br \/>  \u0410 \u0432\u043e\u0442 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a\/\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 <strong>\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e<\/strong> \u0442\u0435\u0441\u0442\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0431\u044b \u0432\u0441\u0435 \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0442\u0435\u0441\u0442\u0435 \u0434\u0435\u043b\u0430\u043b \u0447\u0435\u043b\u043e\u0432\u0435\u043a.<\/p><\/blockquote>\n<p>\u041e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u043d\u0430\u0440\u0443\u0448\u0430\u0442\u044c \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0438\u043c\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/li>\n<li>\u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0411\u0414 (\u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438)<\/li>\n<li>\u0448\u0430\u0431\u043b\u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d \u0432 BDD \u0441\u0442\u0438\u043b\u0435<\/li>\n<li>\u0448\u0430\u0431\u043b\u043e\u043d \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u043c (\u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u043e)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 <strong>Kotest<\/strong>. \u041e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438 \u043a\u0430\u043a \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438\u043c\u0438 \u0441\u0438\u043b\u0430\u043c\u0438 \u0447\u0435\u0440\u0435\u0437 <code>scope<\/code>-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f.<br \/>  \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0441 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">2 \u0432\u0438\u0434\u0430 \u0444\u0430\u0431\u0440\u0438\u043a \u0442\u0435\u0441\u0442\u043e\u0432. TestFactory \u0438 scope-\u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">class FactorySpec : FreeSpec() {     init {         \/*1.1*\/include(containerFactory(1, 2, log))         &quot;root container&quot; - {             \/*2.1*\/containerTemplate()         }     } }  \/** Kotest factory *\/ fun containerFactory(argument1: Any, argument2: Any, logger: Logger) =     \/*1.2*\/freeSpec {     beforeContainer { logger.info(&quot;This 'beforeContainer' callback located in the test factory&quot;) }      &quot;factory container&quot; - {         &quot;factory test with argument1 = $argument1&quot; { }         &quot;factory test with argument2 = $argument2&quot; { }     } }  \/** Add [TestType.Container] by scope function extension *\/ \/*2.2*\/suspend inline fun FreeScope.containerTemplate(): Unit {     &quot;template container with FreeScope context&quot; - {         \/*2.3*\/testCaseTemplate()     } }  \/** Add [TestType.Test] by scope function extension *\/ \/*2.4*\/suspend inline fun FreeScope.testCaseTemplate() {     &quot;nested template testcase with FreeScope context&quot; { } }  private val log = LoggerFactory.getLogger(FactorySpec::class.java)<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h5 id=\"testfactory\">TestFactory<\/h5>\n<p>  <\/p>\n<p><code>1.1<\/code> \u2014 \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>fun include(factory: TestFactory)<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d \u0442\u0435\u0441\u0442\u0430 \u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<p><code>1.2<\/code> \u2014 \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>containerFactory<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 <code>TestFactory<\/code> \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>TestFactory<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>fun freeSpec(block: FreeSpecTestFactoryConfiguration.() -&gt; Unit): TestFactory<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u043b\u043e\u043a \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 <code>FreeSpecTestFactoryConfiguration<\/code>.<br \/>  \u0412\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043f\u0438\u0448\u0435\u043c \u0442\u0435\u0441\u0442, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0432 BDD \u0441\u0438\u043b\u0435. \u0414\u0430\u043b\u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>include<\/code>\u0448\u0430\u0431\u043b\u043e\u043d \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<blockquote><p>\u0414\u043b\u044f <code>TestFactory<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u0447\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0434\u043b\u044f \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u0443\u0434\u0430 \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0448\u0430\u0431\u043b\u043e\u043d.<br \/>  \u0410 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432\u0441\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0431\u0440\u0438\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>beforeContainer<\/code>.<br \/>  \u0423 <code>TestFactory<\/code> \u0435\u0441\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f:  <\/p>\n<ul>\n<li>\u043d\u0435\u043b\u044c\u0437\u044f \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c <code>include<\/code> \u0434\u0440\u0443\u0433 \u0432 \u0434\u0440\u0443\u0433\u0430<\/li>\n<li>\u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0442\u043e \u0435\u0441\u0442\u044c \u0444\u0430\u0431\u0440\u0438\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u043c \u0442\u0435\u0441\u0442\u043e\u043c, \u0430 \u043d\u0435 \u0447\u0430\u0441\u0442\u044c\u044e \u0442\u0435\u0441\u0442\u0430.<\/li>\n<\/ul>\n<p>  <\/p><\/blockquote>\n<p>  <\/p>\n<h5 id=\"shablony-cherez-scope-funkcii-i-funkcii-rasshireniya\">\u0428\u0430\u0431\u043b\u043e\u043d\u044b \u0447\u0435\u0440\u0435\u0437 <code>scope<\/code>-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f.<\/h5>\n<p>  <\/p>\n<p><code>2.1<\/code> \u2014 \u0412\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>containerTemplate<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u043e\u0432\u044b\u0435 \u0448\u0430\u0433\u0438 \u0442\u0435\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<p><code>2.2<\/code> \u2014 \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>suspend inline fun FreeScope.containerTemplate(): Unit<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u0432\u043e\u0439 \u043a\u043e\u0434 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430 <code>FreeScope<\/code> \u0438 \u043f\u0440\u043e\u0441\u0442\u043e <strong>\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442<\/strong> \u044d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u043d\u043e\u0432\u044b\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440.<br \/>  \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442 (<code>side-effect<\/code>) \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u0422\u0435\u0441\u0442\u044b \u043f\u0438\u0448\u0435\u043c \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u043e\u043d\u0438 \u043d\u0435 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0430 \u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<br \/>  <code>suspend<\/code> \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d, \u0442.\u043a. \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0435.<br \/>  <code>inline<\/code> \u2014 \u0434\u043b\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0443 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u0434 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u0432 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0435, \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 <code>containerTemplate<\/code>, \u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<br \/>  <code>FreeScope.<\/code> \u2014 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430<\/p>\n<p>  <\/p>\n<p><code>2.3<\/code> \u2014 \u0412\u043d\u0443\u0442\u0440\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043d\u043e\u0432\u044b\u0435 \u0448\u0430\u0433\u0438. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c <strong>\u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442<\/strong><\/p>\n<p>  <\/p>\n<p><code>2.4<\/code> \u2014 \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>suspend inline fun FreeScope.testCaseTemplate(): Unit<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0448\u0430\u0433\u0438 \u0442\u0435\u0441\u0442\u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0430. \u0412\u0441\u0435 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 <code>2.2<\/code><\/p>\n<p>  <\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0438\u043c\u0435\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0442\u0435\u0441\u0442\u0430 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/p-\/ie\/zr\/p-iezrb-ceh51xhmesr5fvmlico.png\"><\/p>\n<p>  <\/p>\n<h3 id=\"property-testirovanie\">Property \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0432 90-\u0445 \u0433\u043e\u0434\u0430\u0445 \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u0433\u0434\u0435 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0438 \u0435\u0441\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043d\u0430 \u0432\u0441\u0435\u043e\u0431\u044a\u0435\u043c\u043b\u044e\u0449\u0435\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u043d\u0430 \u0432\u0441\u0435\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0439.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043d\u0430\u0431\u043e\u0440, \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0438\u043f \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043f\u0430\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u2014 Data-Driver \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. <\/p>\n<p>  <\/p>\n<p>\u0412 \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043b\u0438\u0431\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. <\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043c\u0435\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043d\u043e \u0438 \u043b\u0435\u0433\u043a\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438: \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u0442.\u043f. <\/p>\n<p>  <\/p>\n<p>\u041d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0432\u0430\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u043e\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043e\u0448\u0438\u0431\u043a\u0443. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<p>  <\/p>\n<h4 id=\"generatory-dannyh\">\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445<\/h4>\n<p>  <\/p>\n<p>\u0412 Kotest \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 2 \u0442\u0438\u043f\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>Arb<\/code> (Arbitrary \u2014 \u0421\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439) \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u0442\u0435\u0441\u0442\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f 1000 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/li>\n<li><code>Exhaustive<\/code> (\u0418\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0438\u0439) \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u0430\u043d \u0432 <a href=\"https:\/\/kotest.io\/docs\/proptest\/property-test-generators-list.html\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a><\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c Property-\u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0438\u0445 \u043e\u0441\u043d\u043e\u0432\u0435. \u0412\u0442\u043e\u0440\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u0430\u044f \u0446\u0435\u043b\u044c \u2014 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0422\u0430\u043a\u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0448\u0438\u0440\u043e\u043a\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0435\u0434\u0438\u043d\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438\u043b\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0441 \u0443\u0441\u043f\u0435\u0445\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 Data-Driven \u0442\u0435\u0441\u0442\u0430\u0445:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 Arb \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"kotlin\">\/** For string generator with leading zero *\/ \/*1*\/val numberCodepoint: Arb&lt;Codepoint&gt; = Arb.int(0x0030..0x0039)         .map { Codepoint(it) }  \/** For english string generator *\/ \/*2*\/val engCodepoint: Arb&lt;Codepoint&gt; = Arb.int('a'.toInt()..'z'.toInt())     .merge(Arb.int('A'.toInt()..'Z'.toInt()))     .map { Codepoint(it) }  class GeneratorSpec : FreeSpec() {     init {         \/*3*\/&quot;random number supported leading zero&quot; {             Arb.string(10, numberCodepoint).next()                 .also(::println)         }          \/*4*\/&quot;random english string&quot; {             Arb.string(10, engCodepoint).orNull(0.5).next()                 .also(::println)         }          \/*5*\/&quot;random russian mobile number&quot; {             Arb.stringPattern(&quot;+7\\\\(\\\\d{3}\\\\)\\\\d{3}-\\\\d{2}-\\\\d{2}&quot;).next()                 .also(::println)         }          \/*6*\/&quot;exhaustive collection and enum multiply&quot; {             Exhaustive.ints(1..5).times(Exhaustive.enum&lt;Level&gt;()).values                 .also(::println)         }          \/*7*\/&quot;exhaustive collection and enum merge&quot; {             Exhaustive.ints(1..5).merge(Exhaustive.enum&lt;Level&gt;()).values                 .also(::println)         }     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 \u041a\u043b\u0430\u0441\u0441 <code>Codepoint<\/code> \u0437\u0430\u0434\u0430\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0434\u043e\u0432 Unicode. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 <code>Arb<\/code> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u043e\u043a.<br \/>  \u0412 <strong>Kotest<\/strong> \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0431\u043e\u0440\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>io.kotest.property.arbitrary.codepoints<\/code>.<br \/>  \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043d\u0430\u0431\u043e\u0440 Unicode \u0446\u0438\u0444\u0440 (\u0442\u0430\u043a\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440 \u043d\u0435\u0442 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445). \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u0448\u0430\u0433\u0430\u0445 \u044d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u043c\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u043d\u0430 <code>0<\/code><\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043d\u0430\u0431\u043e\u0440 \u0431\u0443\u043a\u0432 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430. \u0422.\u043a. \u0432 Unicode \u043e\u043d\u0438 \u0438\u0434\u0443\u0442 \u043d\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443, \u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0431\u043e\u0440 \u043c\u0430\u043b\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430, \u043f\u043e\u0442\u043e\u043c <code>merge<\/code> \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430.<\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0431\u043e\u0440\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0446\u0438\u0444\u0440 <code>numberCodepoint<\/code> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u043c\u0435\u0440\u043e\u0432, \u0433\u0434\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u0435\u043d <code>0<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0442\u0438\u043f\u0430 <code>String<\/code>, \u0434\u043b\u0438\u043d\u0430 10 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<p><code>4<\/code> \u2014 \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u0431\u043e\u0440\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442 <code>engCodepoint<\/code> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043b\u043e\u0432 \u0434\u043b\u0438\u043d\u043e\u0439 10 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0441 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c\u044e 50% \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f <code>null<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 <code>orNull(0.5)<\/code><\/p>\n<p>  <\/p>\n<p><code>5<\/code> \u2014 \u041c\u0435\u0442\u043e\u0434 <code>Arb.stringPattern<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 RegEx \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0430 \u2014 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/github.com\/mifmif\/Generex\">Generex<\/a>. \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0436\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<br \/>  \u0414\u043b\u044f \u043d\u043e\u043c\u0435\u0440\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 10 \u0440\u0430\u0437 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 <code>Arb.string(10,numberCodepoint)<\/code> \u0441 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c. \u0423 \u043c\u0435\u043d\u044f <strong>1000<\/strong> \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0439 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u043f\u043e \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 -&gt; <strong>294 \u043c\u0441<\/strong> \u0438 1000 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0439 \u0442\u0435\u043b\u0435\u0444\u043e\u043d\u0430 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438 \u0446\u0438\u0444\u0440 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c -&gt; <strong>32 \u043c\u0441<\/strong>.<br \/>  \u0417\u0430\u043c\u0435\u0440\u044f\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>measureTimeMillis<\/code>.<\/p>\n<p>  <\/p>\n<p><code>6<\/code> \u2014 <code>Exhaustive<\/code> \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u0435\u0440\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u043c\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 Property-\u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u043e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430\u0431\u043e\u0440\u0430 <code>Int<\/code> \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u044b <code>enum Level<\/code> \u0438 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 25 <code>Pair<\/code>. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0442\u0435\u0441\u0442, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 25 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u044b.<\/p>\n<p>  <\/p>\n<p><code>7<\/code> \u2014 <code>Exhaustive<\/code> \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0432 \u043e\u0434\u043d\u0443 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u0438\u0437 10 \u0440\u0430\u0437\u043d\u043e\u0440\u043e\u0434\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u0438\u0434\u0430: <code>[1, ERROR, 2, WARN ...]<\/code><\/p>\n<p>  <\/p>\n<blockquote><p>\u0412\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Property-\u0442\u0435\u0441\u0442\u043e\u0432, \u043d\u043e \u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u044b \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/>  \u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <code>Arb.next<\/code><\/p><\/blockquote>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ Test 1 2198463900 \/\/ Test 2 tcMPeaTeXG \/\/ Test 3 +7(670)792-05-16 \/\/ Test 4 [(1, ERROR), (1, WARN), (1, INFO), (1, DEBUG), (1, TRACE), (2, ERROR), (2, WARN), (2, INFO), (2, DEBUG), (2, TRACE), (3, ERROR), (3, WARN), (3, INFO), (3, DEBUG), (3, TRACE), (4, ERROR), (4, WARN), (4, INFO), (4, DEBUG), (4, TRACE), (5, ERROR), (5, WARN), (5, INFO), (5, DEBUG), (5, TRACE)] \/\/ Test 5 [1, ERROR, 2, WARN, 3, INFO, 4, DEBUG, 5, TRACE]<\/code><\/pre>\n<p>  <\/p>\n<h4 id=\"napisanie-i-konfigurirovanie-property-testov\">\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 Property \u0442\u0435\u0441\u0442\u043e\u0432<\/h4>\n<p>  <\/p>\n<p><strong>Kotest<\/strong> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Property-\u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u0445 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li><code>suspend inline fun &lt;reified A&gt; forAll(crossinline property: PropertyContext.(A) -&gt; Boolean)<\/code><\/li>\n<li><code>suspend inline fun &lt;reified A&gt; checkAll(noinline property: suspend PropertyContext.(A) -&gt; Unit)<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041e\u0442\u043b\u0438\u0447\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u0432 <code>forAll<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>Boolean<\/code>, \u0430 \u0432 <code>checkAll<\/code> \u0432\u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c 1000 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u043a\u043e\u0434\u0430 \u0441\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0447\u0438\u0441\u043b\u043e\u043c \u0442\u0438\u043f\u0430 <code>Long<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">checkAll&lt;Long&gt; { long: Long -&gt;     val attempt = this.attempts()     println(&quot;#$attempt - $long&quot;)     long.shouldNotBeNull() }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 <code>forAll<\/code> \u0438 <code>checkAll<\/code> \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0435, \u0430 \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c!<\/p>\n<p>  <\/p>\n<p><code>suspend PropertyContext.(A) -&gt; Unit<\/code> \u2014 \u0438\u043c\u0435\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 generic \u0442\u0438\u043f\u0430 (\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e <code>long: Long<\/code>), \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0443 <code>PropertyContext<\/code>, \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e <code>this<\/code> (\u0434\u043b\u044f \u043a\u0440\u0430\u0441\u043e\u0442\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c).<\/p>\n<p>  <\/p>\n<p><code>val attempt = this.attempts()<\/code> \u2014 \u0437\u0434\u0435\u0441\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043b-\u0432\u043e \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043f\u044b\u0442\u043e\u043a \u0438\u0437 <code>PropertyContext<\/code>, \u043d\u043e \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<p>  <\/p>\n<h5 id=\"polzovatelskie-generatory\">\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b<\/h5>\n<p>  <\/p>\n<p>\u0423 \u043e\u0431\u043e\u0438\u0445 \u0432\u0438\u0434\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 (<code>Arb<\/code> \u0438 <code>Exhaustive<\/code>) \u0435\u0441\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b <code>forAll<\/code> \u0438 <code>checkAll<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0431\u043b\u043e\u043a \u0442\u0435\u0441\u0442\u0430, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0438\u0439 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  <\/p>\n<h6 id=\"arb\">Arb<\/h6>\n<p>  <\/p>\n<p><strong>\u0417\u0430\u0434\u0430\u0447\u0430<\/strong>: \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Property-\u0442\u0435\u0441\u0442\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0435\u043e\u0440\u0435\u043c\u044b \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u0438: \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u0430\u0442\u0443\u0440\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0447\u0438\u0441\u0435\u043b. \u0422\u0430\u043a\u0436\u0435 \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f.<br \/>  \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 Kotlin \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0440\u0430\u0437\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0435\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.<br \/>  \u041a\u043e\u0434 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/kochetkov-ma\/pump-samples\/blob\/master\/qa-kotest-articles\/kotest-second\/src\/test\/kotlin\/ru\/iopump\/qa\/sample\/property\/PropertySpec.kt#L49\">\u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445<\/a><\/p>\n<p>  <\/p>\n<p><strong>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439<\/strong>: \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u0438 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0438 \u0438\u0445 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0447\u0438\u0441\u043b\u0443 \u2014 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430.<br \/>  \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438 10 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0442\u0435\u0441\u0442 \u043d\u0430 1000 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0432\u0435\u043b\u0438\u0447\u0438\u043d, \u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong>: \u041a\u043e\u043b-\u0432\u043e = 1000. \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 1. \u0412 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0430 \u0447\u0438\u0441\u043b\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435: <code>2<\/code> \u0438 <code>2147483647<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">&quot;Basic theorem of arithmetic. Any number can be factorized to list of prime&quot; {     \/*1*\/Arb.int(2..Int.MAX_VALUE).withEdgecases(2, Int.MAX_VALUE).forAll(1000) { number -&gt;     val primeFactors = number.primeFactors     println(&quot;#${attempts()} Source number '$number' = $primeFactors&quot;)     \/*2*\/primeFactors.all(Int::isPrime) &amp;&amp; primeFactors.reduce(Int::times) == number }      \/*3*\/Arb.int(2..Int.MAX_VALUE).checkAll(1000) { number -&gt;     val primeFactors = number.primeFactors     println(&quot;#${attempts()} Source number '$number' = $primeFactors&quot;)     \/*4*\/primeFactors.onEach { it.isPrime.shouldBeTrue() }.reduce(Int::times) shouldBe number } }<\/code><\/pre>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430 1000 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439, \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043e\u0442 2 \u0434\u043e Int.MAX_VALUE \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>withEdgecases<\/code>\u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c 2 \u0438 Int.MAX_VALUE \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<br \/>  \u041c\u0435\u0442\u043e\u0434\u043e\u043c <code>forAll<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u043b\u043e\u043a\u0430 \u0442\u0435\u0441\u0442\u0430 <code>Boolean<\/code>. <code>AssertionError<\/code> \u0414\u0432\u0438\u0436\u043e\u043a \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442 \u0437\u0430 \u043d\u0430\u0441, \u0435\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>false<\/code>.<\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 \u043c\u0435\u0442\u043e\u0434 <code>all<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043c\u0435\u0442\u043e\u0434 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043c\u0435\u0442\u043e\u0434 <code>reduce<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u044a\u044e\u043d\u043a\u0446\u0438\u044e \u0434\u0432\u0443\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.<\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 \u0432\u0441\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>1<\/code>. \u041e\u0442\u043b\u0438\u0447\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0431\u043b\u043e\u043a \u043a\u043e\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c <code>Boolean<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 <code>Assertions<\/code>, \u043a\u0430\u043a \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0442\u0435\u0441\u0442\u0435.<\/p>\n<p>  <\/p>\n<p><code>4<\/code> \u2014 \u0432\u043c\u0435\u0441\u0442\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 <strong>Kotest<\/strong><\/p>\n<p>  <\/p>\n<h6 id=\"exhaustive\">Exhaustive<\/h6>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u0441\u0447\u0435\u0440\u043f\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u0441\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e <code>Arb<\/code> \u043f\u043e\u0434\u0445\u043e\u0434\u0443.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 enum <code>UUIDVersion<\/code> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f <code>UUID<\/code>. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c <code>null<\/code> \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>UUID<\/code> \u0442\u0438\u043f\u0430 <code>UUIDVersion.ANY<\/code>.<br \/>  \u0421\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430: <code>fun UUIDVersion?.generateUuid(): UUID<\/code><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e <strong>\u0432\u0441\u0435<\/strong> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>UUIDVersion<\/code> + <code>null<\/code>.<br \/>  \u041d\u0435 \u0438\u043c\u0435\u044f \u0437\u043d\u0430\u043d\u0438\u0439 \u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445 <code>Exhaustive<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0446\u0438\u043a\u043b\u0435. \u041e\u0434\u043d\u0430\u043a\u043e <code>Exhaustive<\/code> \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0438 \u0431\u0435\u0437 \u0442\u043e\u0433\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">&quot;UUIDVersion should be matched with regexp&quot; {     \/*1*\/Exhaustive.enum&lt;UUIDVersion&gt;().andNull().checkAll { uuidVersion -&gt;     \/*2*\/uuidVersion.generateUuid().toString()     \/*3*\/.shouldBeUUID(uuidVersion ?: UUIDVersion.ANY)     .also { println(&quot;${attempts()} $uuidVersion: $it&quot;) } } }<\/code><\/pre>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 <code>reified<\/code> \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Exhaustive.enum<\/code> \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 <code>UUIDVersion<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 <code>null<\/code>, \u0430 \u0434\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d Property-\u0442\u0435\u0441\u0442<\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 \u0432\u044b\u0437\u043e\u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438-\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 <code>UUID<\/code><\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u0430\u044f \u0432 <strong>Kotest<\/strong> \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 <code>UUID<\/code> \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u043c\u0443 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044e<\/p>\n<p>  <\/p>\n<h5 id=\"generatory-po-umolchaniyu\">\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e<\/h5>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>forAll<\/code> \u0438 <code>checkAll<\/code> \u0431\u0435\u0437 \u044f\u0432\u043d\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0442\u0438\u043f\u0430 <code>Arb<\/code> \u0438\u043b\u0438 <code>Exhaustive<\/code>, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 <code>Generic-\u0442\u0438\u043f\u0430<\/code>.<br \/>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f <code>forAll&lt;String&gt;{ }<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 <code>Arb.string()<\/code>. \u0412\u043e\u0442 \u043f\u043e\u043b\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0438\u0437 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 <strong>Kotest<\/strong>:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">fun &lt;A&gt; defaultForClass(kClass: KClass&lt;*&gt;): Arb&lt;A&gt;? {     return when (kClass.bestName()) {         &quot;java.lang.String&quot;, &quot;kotlin.String&quot;, &quot;String&quot; -&gt; Arb.string() as Arb&lt;A&gt;         &quot;java.lang.Character&quot;, &quot;kotlin.Char&quot;, &quot;Char&quot; -&gt; Arb.char() as Arb&lt;A&gt;         &quot;java.lang.Long&quot;, &quot;kotlin.Long&quot;, &quot;Long&quot; -&gt; Arb.long() as Arb&lt;A&gt;         &quot;java.lang.Integer&quot;, &quot;kotlin.Int&quot;, &quot;Int&quot; -&gt; Arb.int() as Arb&lt;A&gt;         &quot;java.lang.Short&quot;, &quot;kotlin.Short&quot;, &quot;Short&quot; -&gt; Arb.short() as Arb&lt;A&gt;         &quot;java.lang.Byte&quot;, &quot;kotlin.Byte&quot;, &quot;Byte&quot; -&gt; Arb.byte() as Arb&lt;A&gt;         &quot;java.lang.Double&quot;, &quot;kotlin.Double&quot;, &quot;Double&quot; -&gt; Arb.double() as Arb&lt;A&gt;         &quot;java.lang.Float&quot;, &quot;kotlin.Float&quot;, &quot;Float&quot; -&gt; Arb.float() as Arb&lt;A&gt;         &quot;java.lang.Boolean&quot;, &quot;kotlin.Boolean&quot;, &quot;Boolean&quot; -&gt; Arb.bool() as Arb&lt;A&gt;         else -&gt; null     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">&quot;check 1000 Long numbers&quot; {     checkAll&lt;Long&gt; { long -&gt;         long.shouldNotBeNull()     } }<\/code><\/pre>\n<p>  <\/p>\n<h5 id=\"seed\">Seed<\/h5>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e Property-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u044d\u0442\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043e\u0448\u0438\u0431\u043a\u0438. \u0414\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435, \u043a\u0430\u043a <strong>seed<\/strong>.<br \/>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u0441\u0435\u0432\u0434\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0435\u043a\u0438\u0439 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (seed), \u0438 \u0434\u043b\u044f \u0440\u0430\u0432\u043d\u044b\u0445 seed \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u0440\u0430\u0432\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<br \/>  C\u0435\u043c\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0439 \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u0440\u0435\u043c\u044f \u043b\u0438\u0431\u043e \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043e\u0448\u0438\u0431\u043a\u0438, <strong>Kotest<\/strong> \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 \u0441\u0435\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0430 \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">&quot;print seed on fail&quot; {     \/*1*\/shouldThrow&lt;AssertionError&gt; {     checkAll&lt;Int&gt; { number -&gt;         println(&quot;#${attempts()} $number&quot;)         \/*2*\/number.shouldBeGreaterThanOrEqual(0)     } }.\/*3*\/message.shouldContain(&quot;Repeat this test by using seed -?\\\\d+&quot;.toRegex()) } &quot;test with seed will generate the same sequence&quot; {     Arb.int().checkAll(\/*4*\/ PropTestConfig(1234567890)) { number -&gt;         \/*5*\/if (attempts() == 24) number shouldBe 196548668         if (attempts() == 428) number shouldBe -601350461         if (attempts() == 866) number shouldBe 1742824805     } }<\/code><\/pre>\n<p>  <\/p>\n<p><code>1<\/code> \u2014 \u041e\u0436\u0438\u0434\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <code>AssertionError<\/code> \u0441 \u0441\u0435\u043c\u0435\u043d\u0435\u043c.<\/p>\n<p>  <\/p>\n<p><code>2<\/code> \u2014 \u0418\u0437 1000 \u0447\u0438\u0441\u0435\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 0 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0441\u0440\u0430\u0437\u0443<\/p>\n<p>  <\/p>\n<p><code>3<\/code> \u2014 \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f, \u0447\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0447\u0438\u0441\u043b\u0435 <strong>seed<\/strong><\/p>\n<p>  <\/p>\n<p><code>4<\/code> \u2014 \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u044f\u0432\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0441\u0435\u043c\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 <code>PropTestConfig<\/code>. \u041e\u0436\u0438\u0434\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b<\/p>\n<p>  <\/p>\n<p><code>5<\/code> \u2014 <code>attempts()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0414\u043b\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 24, 428, 866 \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0447\u0438\u0441\u043b\u0430<\/p>\n<p>  <\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b <a href=\"https:\/\/github.com\/kochetkov-ma\/pump-samples\/tree\/master\/qa-kotest-articles\/kotest-second\/src\">qa-kotest-articles\/kotest-second<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0411\u044b\u043b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0435\u0441\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b <strong>Kotest<\/strong><\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f, \u0430 \u0434\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u043f\u043e\u043c\u043e\u0433\u0430\u044e\u0449\u0438\u043c\u0438 \u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<p>  <\/p>\n<h2>\u0420\u0435\u0441\u0443\u0440\u0441\u044b<\/h2>\n<p>  <\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/520380\/\">Kotlin. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u0447\u0430\u0441\u0442\u044c 1). Kotest: \u041d\u0430\u0447\u0430\u043b\u043e<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/kochetkov-ma\/pump-samples\/tree\/master\/qa-kotest-articles\/kotest-second\/src\">\u041f\u0440\u0438\u043c\u0435\u0440\u044b \u043a\u043e\u0434\u0430<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/kotest.io\/docs\/quickstart\">\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f Kotest<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/kotest\/kotest\">Kotest GitHub<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/kotlinlang.org\/docs\/home.html\">Kotlin Lang<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/kotlinlang.org\/docs\/coroutines-basic-jvm.html\">Coroutines Tutorial<\/a><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/docs.gradle.org\/current\/userguide\/java_testing.html\">Gradle Testing<\/a><\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/nspk\/blog\/542754\/\"> https:\/\/habr.com\/ru\/company\/nspk\/blog\/542754\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/cj\/zc\/qd\/cjzcqdkrw3ru3nxv04yeo-vbz0g.jpeg\" alt=\"Kotest\"><\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0446\u0438\u043a\u043b\u0430 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 \u043f\u0440\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 <strong>Kotlin<\/strong><br \/>  \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 <strong>Kotest<\/strong> \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e \u0441 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044e\u0449\u0438\u043c\u0438 \u0438 \u0443\u0441\u043a\u043e\u0440\u044f\u044e\u0449\u0438\u043c\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0443\u0433\u043b\u0443\u0431\u0438\u043c\u0441\u044f \u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Kotest:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0438 \u0442\u0435\u0441\u0442\u044b<\/li>\n<li>\u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u0440\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439<\/li>\n<li>\u0438\u0437\u0443\u0447\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/li>\n<li>\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b \u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432<\/li>\n<li>\u043f\u0440\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0438 <strong>Flaky<\/strong>-\u0442\u0435\u0441\u0442\u044b<\/li>\n<li>\u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 <strong>\u0424\u0430\u0431\u0440\u0438\u043a \u0442\u0435\u0441\u0442\u043e\u0432<\/strong><\/li>\n<li>\u0438 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0438\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0442\u0435\u043c\u0443 <strong>Property Testing<\/strong><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430:<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/habr.com\/ru\/post\/520380\/\">\u0427\u0430\u0441\u0442\u044c 1. Kotest: \u041d\u0430\u0447\u0430\u043b\u043e<\/a><br \/>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-318324","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318324","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=318324"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/318324\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=318324"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=318324"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=318324"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}