{"id":333282,"date":"2022-05-18T09:00:29","date_gmt":"2022-05-18T09:00:29","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=333282"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=333282","title":{"rendered":"<span>\u0411\u043b\u0435\u0441\u043a \u0438 \u043d\u0438\u0449\u0435\u0442\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Groovy \u0434\u043b\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0438\u043d\u0433\u0430 end-to-end \u0442\u0435\u0441\u0442\u043e\u0432<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/045\/46c\/17d\/04546c17d4f331206e2dd1a12e5b6d49.jpg\" width=\"1353\" height=\"761\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/045\/46c\/17d\/04546c17d4f331206e2dd1a12e5b6d49.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043d\u0434\u0440\u0435\u0439, \u044f BigData Java \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 groovy \u0431\u0435\u0437 gradle, maven \u0438 \u0434\u0430\u0436\u0435 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0447\u0435\u043c\u0443 JUnit 5 &#8212; \u044d\u0442\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f unit \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438 \u0443\u0445\u043e\u0434\u044f\u0442. \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f. \u041a\u0430\u043a \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u041d\u0435 \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0434\u0430\u0442\u044c \u043d\u0430 \u043e\u0442\u043a\u0443\u043f unit \u0442\u0435\u0441\u0442\u0430\u043c, \u043d\u0443\u0436\u043d\u044b end-to-end \u0442\u0435\u0441\u0442\u044b. \u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0435. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u044d\u0442\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u0441\u043b\u043e\u0436\u043d\u043e, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e (\u0432\u0435\u0434\u044c \u0432\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442, \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u044d\u0442\u043e \u043f\u043b\u0435\u0432\u043e\u0435 \u0434\u0435\u043b\u043e). \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u043e\u0434\u0443 \u043d\u0430 \u0445\u0430\u0431\u0440\u0435 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0432\u044b\u0448\u043b\u0430 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/habr.com\/ru\/company\/jugru\/blog\/661623\/\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e (\u043d\u0435) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u0432<\/a>.<\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u043c\u043d\u043e\u0433\u0438\u0435: \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f Web \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043c\u043e\u043d\u0441\u0442\u0440\u044b \u043a\u0430\u043a Selenium WebDriver.<br \/>\u0425\u043e\u0440\u043e\u0448\u043e, \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u0430\u0440\u0443 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 docker \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0433\u043e\u0442\u043e\u0432\u0430.<br \/>\u041f\u043b\u043e\u0445\u043e, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0434\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c \u0438 \u043d\u0435 \u043f\u0430\u0445\u043d\u0435\u0442.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043a\u0430\u0440\u0442\u044b \u0441\u043e\u0448\u043b\u0438\u0441\u044c \u0442\u0430\u043a, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Java;<\/p>\n<\/li>\n<li>\n<p>&#171;\u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f&#187;, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c maven\/gradle \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438, \u043d\u043e \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e scp \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u043e ssh.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<ol>\n<li>\n<p>\u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043b\u044e\u0431\u0438\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435 (JUnit, Spock, TestNG, \u0434\u0430 \u0445\u043e\u0442\u044c <a href=\"https:\/\/github.com\/sormuras\/mainrunner\" rel=\"noopener noreferrer nofollow\">\u043a\u043b\u0430\u0441\u0441 c psvm<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 CI \u0441\u0435\u0440\u0432\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0441\u0440\u0435\u0434\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043d\u043e \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0435\u0433\u043e \u0441\u043b\u0435\u0433\u043a\u0430 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c, \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0418\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0438\u0448\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041f\u0430\u0440\u0443 \u0446\u0438\u043a\u043b\u043e\u0432 &#171;\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c&#187;, &#171;\u0441\u043e\u0431\u0440\u0430\u0442\u044c&#187;, &#171;\u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c&#187;, &#171;\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c&#187; \u0438 \u0432\u043e\u0442 \u0443\u0436\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432\u0441\u044f\u043a\u043e\u0435 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u0441\u0442\u043a\u0435\u0439\u0441. \u0422\u0443\u0442 \u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u044b\u0441\u043b\u044c: \u0430 \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438? \u041d\u0435\u043c\u043d\u043e\u0433\u043e vim \u0438\u043b\u0438 nano \u0438 \u043a\u043e\u0434 \u0442\u0435\u0441\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0440\u0435\u0434\u044b.<\/p>\n<p>\u0420\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u0445 \u0432 JVM \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a Groovy. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0432 Groovy \u0437\u0430\u043b\u043e\u0436\u0435\u043d\u0430 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u044f\u043c\u043e \u0432 <a href=\"https:\/\/docs.groovy-lang.org\/4.0.2\/html\/documentation\/#_testing_with_junit\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. Groovy cli \u0443\u043c\u0435\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0442\u0435\u0441\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c google.com, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f Junit Jupiter.<\/p>\n<pre><code class=\"java\">class SampleJunit5 {     @org.junit.jupiter.api.Test     void pingGoogleInJunit5() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google from junit5 test now...\"         assert address.isReachable(60000)     } }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0432\u0435\u0440\u0441\u0438\u044f Groovy 3.0.10.<br \/>\u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0435 \u0441\u0430\u043c\u0438\u043c &#8212; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 Groovy, \u0441\u043b\u0435\u0434\u0443\u044f <a href=\"https:\/\/groovy-lang.org\/\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438<\/a>.<br \/>\u0418\u043b\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0437 <a href=\"https:\/\/github.com\/alopukhov\/habr-samples\/tree\/habr-sample-tests-groovy\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>, \u0432\u0435\u0442\u043a\u0430 <code>habr-sample-tests-groovy<\/code>:<\/p>\n<pre><code class=\"bash\">git clone --branch  habr-sample-tests-groovy git@github.com:alopukhov\/habr-samples.git cd habr-samples .\/gradlew setupWorkspace cd workspace export GROOVY_HOME=\"${PWD}\/groovy-3.0.10\/\" export PATH=\"$GROOVY_HOME\/bin:$PATH\"<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0442\u0435\u0441\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>groovy SampleJunit5.groovy<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u044b\u0445\u043e\u0434 (\u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"http:\/\/google.com\" rel=\"noopener noreferrer nofollow\">google.com<\/a>):<\/p>\n<pre><code>Pinging google from junit5 test now... JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=109ms<\/code><\/pre>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0438 \u0441 \u043d\u0435\u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0442\u0435\u0441\u0442\u043e\u043c:<\/p>\n<pre><code class=\"java\">class FailingTest {   @org.junit.jupiter.api.Test   void thisWillFail() { assert 2 * 2 == 5 }    @org.junit.jupiter.api.Test   void thisWillPass() { assert 2 * 2 == 4 } }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>groovy FailingTest.groovy<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<pre><code>JUnit5 launcher: passed=1, aborted=0, failed=1, skipped=0, time=75ms  Failures (1):   JUnit Jupiter:FailingTest:thisWillFail()     MethodSource [className = 'FailingTest', methodName = 'thisWillFail', methodParameterTypes = '']     => Assertion failed:  assert 2 * 2 == 5          |   |          4   false         org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:436) ... \u0438 \u0435\u0449\u0435 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u043e\u043a \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441\u0430 ...<\/code><\/pre>\n<p>\u0421\u0445\u043e\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u043a\u043e\u0434 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<details class=\"spoiler\">\n<summary>Junit 4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleJunit4 {     @org.junit.Test     void pingGoogleInJunit4() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google from junit4 test now...\"         assert address.isReachable(60000)     } }<\/code><\/pre>\n<pre><code>> groovy SampleJunit4.groovy Pinging google from junit4 test now... JUnit 4 Runner, Tests: 1, Failures: 0, Time: 73<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Spock<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleSpockSpeck extends spock.lang.Specification {     def \"ping google in Spock\"() {         expect:         println \"Pinging google from spock now\"         InetAddress.getByName(\"google.com\").isReachable(60000)     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0436\u0435 \u043d\u0443\u0436\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Spock &#8212; \u043e\u043d\u0430 \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443 Groovy.<br \/>\u0412\u0435\u0440\u0441\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0439 \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 Groovy. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/spockframework.org\/\" rel=\"noopener noreferrer nofollow\">spockframework.org<\/a>.<\/p>\n<pre><code>> groovy -cp .\/libs\/spock-core-2.1-groovy-3.0.jar SampleSpockSpeck.groovy Pinging google from spock now JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=97ms<\/code><\/pre>\n<p>\u0414\u043b\u044f spock 1.x \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0435\u0440\u0441\u0438\u044f groovy 2.5.x.<br \/>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 2, spock \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 junit platform, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0440\u0430\u043d\u044c\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Junit4 runner Sputnik.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>TestNG<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleTestNG {     @org.testng.annotations.Test     void pingGoogleInTestNG() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google now from testng\"         assert address.isReachable(60000)     }  @org.testng.annotations.Test void failInTestNg() { assert false } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 slf4j \u043b\u043e\u0433\u0433\u0435\u0440\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 slf4j-simple.<\/p>\n<pre><code>> groovy -cp .\/libs\/slf4j-simple-1.7.36.jar SampleTestNG.groovy  [main] INFO org.testng.internal.Utils - [TestNG] Running:   Command line suite  Pinging google now from testng  =============================================== Command line suite Total tests run: 2, Passes: 1, Failures: 1, Skips: 0 ===============================================<\/code><\/pre>\n<p>\u0423\u0432\u044b, \u043d\u0435\u0442 \u0434\u0430\u0436\u0435 \u0438\u043c\u0435\u043d\u0438 \u0443\u043f\u0430\u0432\u0448\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c testng \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0443\u0442 \u043a\u0430\u043a.<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0442\u0430\u043a\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <a href=\"https:\/\/docs.groovy-lang.org\/3.0.10\/html\/api\/org\/apache\/groovy\/plugin\/GroovyRunner.html\" rel=\"noopener noreferrer nofollow\">GroovyRunner<\/a>. \u0422\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043d\u0435\u0442\u0438\u043f\u0438\u0447\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 &#8212; \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<br \/>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435\u0431\u043e\u0433\u0430\u0442\u044b\u0439: summary \u043f\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0430\u0434\u0435\u043d\u0438\u044f\u0445. \u0418\u043c\u0435\u043d\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f. \u0410 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 testng \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u043d\u0430 \u0438\u043c\u0435\u043d\u0430 \u0443\u043f\u0430\u0432\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0438\u0435 \u0442\u0435\u0441\u0442\u044b &#8212; \u043a\u0443\u0440\u0430\u043c \u043d\u0430 \u0441\u043c\u0435\u0445.<br \/>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043e\u0431\u0441\u0442\u043e\u044f\u0442 \u0434\u0435\u043b\u0430 \u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438.<br \/>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c 2 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"java\">\/\/content of Calculator.groovy class Calculator {     static long multiply(long a, long b) { a * b } }  \/\/content of SampleWithHelper.groovy class SampleWithHelper {     @org.junit.jupiter.api.Test     void mathTest() { assert 4 == Calculator.multiply(2, 2)} }<\/code><\/pre>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code>> groovy SampleWithHelper.groovy groovy SampleWithHelper.groovy JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=71ms<\/code><\/pre>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c working directory:<\/p>\n<pre><code>> groovy .\/workspace\/SampleWithHelper.groovy JUnit5 launcher: passed=0, aborted=0, failed=1, skipped=0, time=70ms  Failures (1):   JUnit Jupiter:SampleWithHelper:mathTest()     MethodSource [className = 'SampleWithHelper', methodName = 'mathTest', methodParameterTypes = '']     => groovy.lang.MissingPropertyException: No such property: Calculator for class: SampleWithHelper        org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:65) ... \u0438 \u0435\u0449\u0435 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u043e\u043a \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441\u0430 ...<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0435 Calculator. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043c SampleWithHelper \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">import static Calculator.multiply  class SampleWithHelper {     @org.junit.jupiter.api.Test     void mathTest() { assert 4 == multiply(2, 2)} }<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435:<\/p>\n<pre><code>> groovy .\/workspace\/SampleWithHelper.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: C:\\Users\\andre\\IdeaProjects\\habr_scripting_tests_example\\workspace\\SampleWithHelper.groovy: 1: unable to resolve class Calculator  @ line 1, column 1.    import static Calculator.multiply    ^<\/code><\/pre>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c classpath. \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 classpath \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 groovy, \u043d\u043e \u0435\u0441\u043b\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0438\u043d\u043e\u0439 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u044f\u0432\u043d\u043e.<\/p>\n<pre><code>> groovy -cp .\/workspace .\/workspace\/SampleWithHelper.groovy JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=75ms<\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043a\u043e\u043f\u043e\u043c.<\/p>\n<p>\u0418 \u0442\u0443\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 JUnit platform. JUnit 5 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 API, \u043d\u043e \u0446\u0435\u043b\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043e\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432.<br \/>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Suite API:<\/p>\n<pre><code class=\"java\">import org.junit.platform.suite.api.*  @Suite @SuiteDisplayName(\"Sample Suite for Habr\") @SelectClasses([SampleJunit4, SampleJunit5, SampleTestNG, SampleSpockSpeck]) class SuiteTest { }<\/code><\/pre>\n<pre><code>> groovy -cp \"libs\/*\" .\/SuiteTest.groovy Pinging google from junit5 test now... Pinging google from spock now Pinging google now from testng Pinging google from junit4 test now... JUnit5 launcher: passed=4, aborted=0, failed=1, skipped=0, time=226ms  Failures (1):   JUnit Platform Suite:Sample Suite for Habr:TestNG:SampleTestNG:failInTestNg     MethodSource [className = 'SampleTestNG', methodName = 'failInTestNg', methodParameterTypes = '']     => Assertion failed: ... more...<\/code><\/pre>\n<p>N.B. \u041f\u0440\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0438 wildcard classpath \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u043c\u0432\u043e\u043b <code>*<\/code> \u043d\u0435 \u0431\u044b\u043b \u0440\u0430\u0441\u043a\u0440\u044b\u0442 \u043a\u0430\u043a glob pattern. \u0412 Windows \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 groovy.bat \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0439\u0442\u0435 \u043f\u0443\u0442\u0438 \u0432 \u0434\u0432\u043e\u0435\u0442\u043e\u0447\u0438\u044f.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 JUnit5 launcher, \u0432\u0434\u043e\u0431\u0430\u0432\u043e\u043a \u0434\u0430\u0436\u0435 \u0441\u0442\u0430\u043b\u043e \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0443\u043f\u0430\u043b \u0432 TestNG.<\/p>\n<p>\u041d\u043e \u043c\u043e\u0436\u043d\u043e \u043b\u0443\u0447\u0448\u0435. \u0412 JUnit Platform \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>junit-platform-console<\/code> \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438.<br \/>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442:<\/p>\n<pre><code class=\"java\">\/\/content of RunJunitConsole.groovy org.junit.platform.console.ConsoleLauncher.main(args)<\/code><\/pre>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434:<\/p>\n<pre><code>> groovy -cp \"libs\/*\" RunJunitConsole.groovy --select-class SuiteTest --disable-banner --disable-ansi-colors Pinging google from junit4 test now... Pinging google from junit5 test now... Pinging google from spock now Pinging google now from testng . +-- JUnit Jupiter [OK] +-- JUnit Platform Suite [OK] | '-- Sample Suite for Habr [OK] |   +-- JUnit Vintage [OK] |   | '-- SampleJunit4 [OK] |   |   '-- pingGoogleInJunit4 [OK] |   +-- JUnit Jupiter [OK] |   | '-- SampleJunit5 [OK] |   |   '-- pingGoogleInJunit5() [OK] |   +-- Spock [OK] |   | '-- SampleSpockSpeck [OK] |   |   '-- ping google in Spock [OK] |   '-- TestNG [OK] |     '-- SampleTestNG [OK] |       +-- failInTestNg [X] assert false |       '-- pingGoogleInTestNG [OK] +-- JUnit Vintage [OK] +-- Spock [OK] '-- TestNG [OK]  Failures (1):   JUnit Platform Suite:Sample Suite for Habr:TestNG:SampleTestNG:failInTestNg     MethodSource [className = 'SampleTestNG', methodName = 'failInTestNg', methodParameterTypes = '']  ... a bit of stack trace ...  Test run finished after 229 ms [        14 containers found      ] [         0 containers skipped    ] [        14 containers started    ] [         0 containers aborted    ] [        14 containers successful ] [         0 containers failed     ] [         5 tests found           ] [         0 tests skipped         ] [         5 tests started         ] [         0 tests aborted         ] [         4 tests successful      ] [         1 tests failed          ]<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Suite:<\/p>\n<pre><code>> groovy -cp \"libs\/*\" RunJunitConsole.groovy --disable-banner --disable-ansi-colors -e junit-jupiter -c SampleJunit5 -c FailingTest Pinging google from junit5 test now... . '-- JUnit Jupiter [OK]   +-- SampleJunit5 [OK]   | '-- pingGoogleInJunit5() [OK]   '-- FailingTest [OK]     +-- thisWillFail() [X] assert 2 * 2 == 5     |              |   |     |              4   false     '-- thisWillPass() [OK]  ... failure details ...<\/code><\/pre>\n<p>\u041d\u043e \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>--reports-dir<\/code>, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043e\u0442\u0447\u0435\u0442\u044b \u0432 JUnit xml \u0444\u043e\u0440\u043c\u0430\u0442\u0435. \u042d\u0442\u0438 \u043e\u0442\u0447\u0435\u0442\u044b \u0434\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043d\u0435\u0437\u0430\u0434\u0430\u0447\u0430 &#8212; \u0432\u0441\u0435 \u0438\u043c\u0435\u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044f\u0432\u043d\u043e. Classpath \u0438 package scanning \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b, \u0442.\u043a. \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043e\u0436\u0438\u0434\u0430\u044e\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0432 \u043d\u0430\u043f\u0438\u043b\u044c\u043d\u0438\u043a\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 TestEngine.<br \/>\u0422\u0430\u043a, \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0430\u043c\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <a href=\"https:\/\/github.com\/alopukhov\/sybok\" rel=\"noopener noreferrer nofollow\">Sybok Test Engine<\/a>, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0431\u0435\u0437 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u0434\u0438\u0441\u0442\u0440\u0438\u0431\u0443\u0442\u0438\u0432\u0430 groovy.<\/p>\n<pre><code>> java -cp \".\\libs\\*;.\\sybok-libs\\*\" org.junit.platform.console.ConsoleLauncher --disable-banner --disable-ansi-colors -e sybok-engine --config sybok.script-roots=. --config sybok.delegate-engine-ids=spock,junit-jupiter,junit-vintage -d . -n \".*\" Pinging google from spock now Pinging google from junit4 test now... Pinging google from junit5 test now... . '-- Sybok [OK]   +-- Spock [OK]   | '-- SampleSpockSpeck [OK]   |   '-- ping google in Spock [OK]   +-- JUnit Vintage [OK]   | '-- SampleJunit4 [OK]   |   '-- pingGoogleInJunit4 [OK]   '-- JUnit Jupiter [OK]     +-- SampleJunit5 [OK]     | '-- pingGoogleInJunit5() [OK]     +-- FailingTest [OK]     | +-- thisWillFail() [X] assert 2 * 2 == 5     | |              |   |     | |              4   false     | '-- thisWillPass() [OK]     '-- SampleWithHelper [OK]       '-- mathTest() [OK]    ... failure details ...<\/code><\/pre>\n<p>\u041e\u043d (\u043f\u043e\u043a\u0430) \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c TestNG \u043a\u043b\u0430\u0441\u0441\u044b, \u043d\u043e \u0434\u0443\u043c\u0430\u044e \u044d\u0442\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043c\u043e.<\/p>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0435\u0449\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u043f\u043e\u0434 JVM. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Kotlin script.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b\u043b\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445: \u0447\u0442\u043e \u0431\u044b \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 JVM?<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \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\/post\/666334\/\"> https:\/\/habr.com\/ru\/post\/666334\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043d\u0434\u0440\u0435\u0439, \u044f BigData Java \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 groovy \u0431\u0435\u0437 gradle, maven \u0438 \u0434\u0430\u0436\u0435 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u044d\u0442\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0447\u0435\u043c\u0443 JUnit 5 &#8212; \u044d\u0442\u043e \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f unit \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0422\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442 \u0438 \u0443\u0445\u043e\u0434\u044f\u0442. \u0412\u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f. \u041a\u0430\u043a \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438. \u041d\u0435 \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0434\u0430\u0442\u044c \u043d\u0430 \u043e\u0442\u043a\u0443\u043f unit \u0442\u0435\u0441\u0442\u0430\u043c, \u043d\u0443\u0436\u043d\u044b end-to-end \u0442\u0435\u0441\u0442\u044b. \u0416\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u044b\u0435. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f &#8212; \u044d\u0442\u043e \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438 \u0441\u043b\u043e\u0436\u043d\u043e, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e (\u0432\u0435\u0434\u044c \u0432\u0441\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0447\u0438\u0442\u0430\u044e\u0442, \u0447\u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u044d\u0442\u043e \u043f\u043b\u0435\u0432\u043e\u0435 \u0434\u0435\u043b\u043e). \u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u043e\u0434\u0443 \u043d\u0430 \u0445\u0430\u0431\u0440\u0435 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u0432\u044b\u0448\u043b\u0430 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/habr.com\/ru\/company\/jugru\/blog\/661623\/\" rel=\"noopener noreferrer nofollow\">\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e (\u043d\u0435) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u043e\u0432<\/a>.<\/p>\n<p>\u0425\u043e\u0440\u043e\u0448\u043e, \u043a\u043e\u0433\u0434\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u043c\u043d\u043e\u0433\u0438\u0435: \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f Web \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043c\u043e\u043d\u0441\u0442\u0440\u044b \u043a\u0430\u043a Selenium WebDriver.<br \/>\u0425\u043e\u0440\u043e\u0448\u043e, \u043a\u043e\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u0430\u0440\u0443 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 docker \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u0433\u043e\u0442\u043e\u0432\u0430.<br \/>\u041f\u043b\u043e\u0445\u043e, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0434\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u043b\u044e\u0431\u044f\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c \u0438 \u043d\u0435 \u043f\u0430\u0445\u043d\u0435\u0442.<\/p>\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u043a\u0430\u0440\u0442\u044b \u0441\u043e\u0448\u043b\u0438\u0441\u044c \u0442\u0430\u043a, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043d\u0430 Java;<\/p>\n<\/li>\n<li>\n<p>&#171;\u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f&#187;, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u043c \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432 \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c maven\/gradle \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438, \u043d\u043e \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u044b \u043f\u043e scp \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043f\u043e ssh.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<ol>\n<li>\n<p>\u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u043d\u0430 \u043b\u044e\u0431\u0438\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435 (JUnit, Spock, TestNG, \u0434\u0430 \u0445\u043e\u0442\u044c <a href=\"https:\/\/github.com\/sormuras\/mainrunner\" rel=\"noopener noreferrer nofollow\">\u043a\u043b\u0430\u0441\u0441 c psvm<\/a>);<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 CI \u0441\u0435\u0440\u0432\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0435\u043c \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u0443\u044e \u0441\u0440\u0435\u0434\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c;<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043d\u043e \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0448\u0430\u0433\u0430. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439, \u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0435\u0433\u043e \u0441\u043b\u0435\u0433\u043a\u0430 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c, \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0418\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043f\u0438\u0448\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0439 \u0438 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041f\u0430\u0440\u0443 \u0446\u0438\u043a\u043b\u043e\u0432 &#171;\u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c&#187;, &#171;\u0441\u043e\u0431\u0440\u0430\u0442\u044c&#187;, &#171;\u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c&#187;, &#171;\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c&#187; \u0438 \u0432\u043e\u0442 \u0443\u0436\u0435 \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432\u0441\u044f\u043a\u043e\u0435 \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u0441\u0442\u043a\u0435\u0439\u0441. \u0422\u0443\u0442 \u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u044b\u0441\u043b\u044c: \u0430 \u043c\u043e\u0436\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438? \u041d\u0435\u043c\u043d\u043e\u0433\u043e vim \u0438\u043b\u0438 nano \u0438 \u043a\u043e\u0434 \u0442\u0435\u0441\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0435 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0440\u0435\u0434\u044b.<\/p>\n<p>\u0420\u0430\u0437\u043c\u044b\u0448\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u0445 \u0432 JVM \u0440\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a Groovy. \u0412 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0432 Groovy \u0437\u0430\u043b\u043e\u0436\u0435\u043d\u0430 \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u041c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u044f\u043c\u043e \u0432 <a href=\"https:\/\/docs.groovy-lang.org\/4.0.2\/html\/documentation\/#_testing_with_junit\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>. Groovy cli \u0443\u043c\u0435\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438.<\/p>\n<p>\u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0442\u0435\u0441\u0442, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c google.com, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f Junit Jupiter.<\/p>\n<pre><code class=\"java\">class SampleJunit5 {     @org.junit.jupiter.api.Test     void pingGoogleInJunit5() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google from junit5 test now...\"         assert address.isReachable(60000)     } }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0432\u0435\u0440\u0441\u0438\u044f Groovy 3.0.10.<br \/>\u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0435 \u0441\u0430\u043c\u0438\u043c &#8212; \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 Groovy, \u0441\u043b\u0435\u0434\u0443\u044f <a href=\"https:\/\/groovy-lang.org\/\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438<\/a>.<br \/>\u0418\u043b\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438\u0437 <a href=\"https:\/\/github.com\/alopukhov\/habr-samples\/tree\/habr-sample-tests-groovy\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>, \u0432\u0435\u0442\u043a\u0430 <code>habr-sample-tests-groovy<\/code>:<\/p>\n<pre><code class=\"bash\">git clone --branch  habr-sample-tests-groovy git@github.com:alopukhov\/habr-samples.git cd habr-samples .\/gradlew setupWorkspace cd workspace export GROOVY_HOME=\"${PWD}\/groovy-3.0.10\/\" export PATH=\"$GROOVY_HOME\/bin:$PATH\"<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0442\u0435\u0441\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>groovy SampleJunit5.groovy<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u044b\u0445\u043e\u0434 (\u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d <a href=\"http:\/\/google.com\" rel=\"noopener noreferrer nofollow\">google.com<\/a>):<\/p>\n<pre><code>Pinging google from junit5 test now... JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=109ms<\/code><\/pre>\n<p>\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u0430\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0438 \u0441 \u043d\u0435\u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0442\u0435\u0441\u0442\u043e\u043c:<\/p>\n<pre><code class=\"java\">class FailingTest {   @org.junit.jupiter.api.Test   void thisWillFail() { assert 2 * 2 == 5 }    @org.junit.jupiter.api.Test   void thisWillPass() { assert 2 * 2 == 4 } }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c <code>groovy FailingTest.groovy<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c:<\/p>\n<pre><code>JUnit5 launcher: passed=1, aborted=0, failed=1, skipped=0, time=75ms  Failures (1):   JUnit Jupiter:FailingTest:thisWillFail()     MethodSource [className = 'FailingTest', methodName = 'thisWillFail', methodParameterTypes = '']     => Assertion failed:  assert 2 * 2 == 5          |   |          4   false         org.codehaus.groovy.runtime.InvokerHelper.assertFailed(InvokerHelper.java:436) ... \u0438 \u0435\u0449\u0435 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u043e\u043a \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441\u0430 ...<\/code><\/pre>\n<p>\u0421\u0445\u043e\u0436\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438 \u043a\u043e\u0434 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a.<\/p>\n<details class=\"spoiler\">\n<summary>Junit 4<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleJunit4 {     @org.junit.Test     void pingGoogleInJunit4() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google from junit4 test now...\"         assert address.isReachable(60000)     } }<\/code><\/pre>\n<pre><code>> groovy SampleJunit4.groovy Pinging google from junit4 test now... JUnit 4 Runner, Tests: 1, Failures: 0, Time: 73<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Spock<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleSpockSpeck extends spock.lang.Specification {     def \"ping google in Spock\"() {         expect:         println \"Pinging google from spock now\"         InetAddress.getByName(\"google.com\").isReachable(60000)     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0436\u0435 \u043d\u0443\u0436\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Spock &#8212; \u043e\u043d\u0430 \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0443 Groovy.<br \/>\u0412\u0435\u0440\u0441\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0439 \u0441 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 Groovy. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/spockframework.org\/\" rel=\"noopener noreferrer nofollow\">spockframework.org<\/a>.<\/p>\n<pre><code>> groovy -cp .\/libs\/spock-core-2.1-groovy-3.0.jar SampleSpockSpeck.groovy Pinging google from spock now JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=97ms<\/code><\/pre>\n<p>\u0414\u043b\u044f spock 1.x \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0432\u0435\u0440\u0441\u0438\u044f groovy 2.5.x.<br \/>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 2, spock \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 junit platform, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0440\u0430\u043d\u044c\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f Junit4 runner Sputnik.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>TestNG<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">class SampleTestNG {     @org.testng.annotations.Test     void pingGoogleInTestNG() {         def address = InetAddress.getByName(\"google.com\")         println \"Pinging google now from testng\"         assert address.isReachable(60000)     }  @org.testng.annotations.Test void failInTestNg() { assert false } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 slf4j \u043b\u043e\u0433\u0433\u0435\u0440\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 slf4j-simple.<\/p>\n<pre><code>> groovy -cp .\/libs\/slf4j-simple-1.7.36.jar SampleTestNG.groovy  [main] INFO org.testng.internal.Utils - [TestNG] Running:   Command line suite  Pinging google now from testng  =============================================== Command line suite Total tests run: 2, Passes: 1, Failures: 1, Skips: 0 ===============================================<\/code><\/pre>\n<p>\u0423\u0432\u044b, \u043d\u0435\u0442 \u0434\u0430\u0436\u0435 \u0438\u043c\u0435\u043d\u0438 \u0443\u043f\u0430\u0432\u0448\u0435\u0433\u043e \u0442\u0435\u0441\u0442\u0430. \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c testng \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0443\u0442 \u043a\u0430\u043a.<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0442\u0430\u043a\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <a href=\"https:\/\/docs.groovy-lang.org\/3.0.10\/html\/api\/org\/apache\/groovy\/plugin\/GroovyRunner.html\" rel=\"noopener noreferrer nofollow\">GroovyRunner<\/a>. \u0422\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0434\u043b\u044f \u043d\u0435\u0442\u0438\u043f\u0438\u0447\u043d\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 &#8212; \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<br \/>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0432 \u0446\u0435\u043b\u043e\u043c \u043d\u0435\u0431\u043e\u0433\u0430\u0442\u044b\u0439: summary \u043f\u043e \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u0430\u0434\u0435\u043d\u0438\u044f\u0445. \u0418\u043c\u0435\u043d\u0430 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f. \u0410 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 testng \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u043d\u0430 \u0438\u043c\u0435\u043d\u0430 \u0443\u043f\u0430\u0432\u0448\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u0438\u0435 \u0442\u0435\u0441\u0442\u044b &#8212; \u043a\u0443\u0440\u0430\u043c \u043d\u0430 \u0441\u043c\u0435\u0445.<br \/>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043e\u0431\u0441\u0442\u043e\u044f\u0442 \u0434\u0435\u043b\u0430 \u0441 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0442\u0435\u0441\u0442\u043e\u0432 \u0441\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438.<br \/>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c 2 \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"java\">\/\/content of Calculator.groovy class Calculator {     static long multiply(long a, long b) { a * b } }  \/\/content of SampleWithHelper.groovy class SampleWithHelper {     @org.junit.jupiter.api.Test     void mathTest() { assert 4 == Calculator.multiply(2, 2)} }<\/code><\/pre>\n<p>\u0412\u0440\u043e\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<pre><code>> groovy SampleWithHelper.groovy groovy SampleWithHelper.groovy JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=71ms<\/code><\/pre>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c working directory:<\/p>\n<pre><code>> groovy .\/workspace\/SampleWithHelper.groovy JUnit5 launcher: passed=0, aborted=0, failed=1, skipped=0, time=70ms  Failures (1):   JUnit Jupiter:SampleWithHelper:mathTest()     MethodSource [className = 'SampleWithHelper', methodName = 'mathTest', methodParameterTypes = '']     => groovy.lang.MissingPropertyException: No such property: Calculator for class: SampleWithHelper        org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:65) ... \u0438 \u0435\u0449\u0435 \u0441\u043e\u0442\u043d\u0438 \u0441\u0442\u0440\u043e\u043a \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441\u0430 ...<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0435 Calculator. \u0415\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043c SampleWithHelper \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">import static Calculator.multiply  class SampleWithHelper {     @org.junit.jupiter.api.Test     void mathTest() { assert 4 == multiply(2, 2)} }<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043c \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435:<\/p>\n<pre><code>> groovy .\/workspace\/SampleWithHelper.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: C:\\Users\\andre\\IdeaProjects\\habr_scripting_tests_example\\workspace\\SampleWithHelper.groovy: 1: unable to resolve class Calculator  @ line 1, column 1.    import static Calculator.multiply    ^<\/code><\/pre>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c classpath. \u0422\u0435\u043a\u0443\u0449\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 classpath \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 groovy, \u043d\u043e \u0435\u0441\u043b\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0441\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430\u043c\u0438 \u0438\u043d\u043e\u0439 &#8212; \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0435\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u044f\u0432\u043d\u043e.<\/p>\n<pre><code>> groovy -cp .\/workspace .\/workspace\/SampleWithHelper.groovy JUnit5 launcher: passed=1, aborted=0, failed=0, skipped=0, time=75ms<\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u043a\u043e\u043f\u043e\u043c.<\/p>\n<p>\u0418 \u0442\u0443\u0442 \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 JUnit platform. JUnit 5 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u043e\u0432\u043e\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 API, \u043d\u043e \u0446\u0435\u043b\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432 \u043e\u0442 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432.<br \/>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0442\u0435\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Suite API:<\/p>\n<pre><code class=\"java\">import org.junit.platform.suite.api.*  @Suite @SuiteDisplayName(\"Sample Suite for Habr\") @SelectClasses([SampleJunit4, SampleJunit5, SampleTestNG, SampleSpockSpeck]) class SuiteTest { }<\/code><\/pre>\n<pre><code>> groovy -cp \"libs\/*\" .\/SuiteTest.groovy Pinging google from junit5 test now... Pinging google from spock now Pinging google now from testng Pinging google from junit4 test now... JUnit5 launcher: passed=4, aborted=0, failed=1, skipped=0, time=226ms  Failures (1):   JUnit Platform Suite:Sample Suite for Habr:TestNG:SampleTestNG:failInTestNg     MethodSource [className = 'SampleTestNG', methodName = 'failInTestNg', methodParameterTypes = '']     => Assertion failed: ... more...<\/code><\/pre>\n<p>N.B. \u041f\u0440\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0438 wildcard classpath \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0438\u043c\u0432\u043e\u043b <code>*<\/code> \u043d\u0435 \u0431\u044b\u043b \u0440\u0430\u0441\u043a\u0440\u044b\u0442 \u043a\u0430\u043a glob pattern. \u0412 Windows \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 groovy.bat \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0439\u0442\u0435 \u043f\u0443\u0442\u0438 \u0432 \u0434\u0432\u043e\u0435\u0442\u043e\u0447\u0438\u044f.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0442\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 JUnit5 launcher, \u0432\u0434\u043e\u0431\u0430\u0432\u043e\u043a \u0434\u0430\u0436\u0435 \u0441\u0442\u0430\u043b\u043e \u0432\u0438\u0434\u043d\u043e, \u043a\u0430\u043a\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0443\u043f\u0430\u043b \u0432 TestNG.<\/p>\n<p>\u041d\u043e \u043c\u043e\u0436\u043d\u043e \u043b\u0443\u0447\u0448\u0435. \u0412 JUnit Platform \u0435\u0441\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <code>junit-platform-console<\/code> \u0434\u043b\u044f<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-333282","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/333282","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=333282"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/333282\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=333282"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=333282"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=333282"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}