{"id":326210,"date":"2021-07-09T15:00:18","date_gmt":"2021-07-09T15:00:18","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=326210"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=326210","title":{"rendered":"\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 Go + Allure"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u043f\u0438\u0441\u0430\u043b\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 Go <\/p>\n<\/li>\n<li>\n<p>\u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c<\/p>\n<\/li>\n<li>\n<p>\u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u044f \u0442\u0435\u0445:<\/p>\n<ul>\n<li>\n<p>\u043a\u0442\u043e \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 Go, \u043a\u0430\u043a \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u044f<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 Go \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e \u0447\u0435\u043c \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c<\/strong>:<\/p>\n<ul>\n<li>\n<p><a href=\"#1\">\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 Go \u0438 Allure<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\">\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 Allure-go \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\">\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 Allure-go<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\">Assertion-\u044b \u0432 go, \u0432\u044b\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\">O gomega<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\">\u041a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c gomega \u0441 allure<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\">\u041f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0442\u0435\u0441\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#8\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 REST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#9\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#10\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#11\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 dependency injection<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#12\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u0447\u0435\u0442\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u0432 Gitlab-CI<\/a><\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p>Unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 (\u041c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435) \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<\/p>\n<p>Allure \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0447\u0435\u0442\u044b \u043d\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u0412 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441 \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432 \u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0441\u043d\u043e \u043e\u0442\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u0441\u0441\u0430\u043c \u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 =)<\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"1\" id=\"1\"><\/a><\/p>\n<h2>\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 Go \u0438 Allure<\/h2>\n<p>\u0412 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445: Java, Kotlin, Scala \u0438 Go. \u0412 \u043c\u043e\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435&nbsp;\u2014 Go.&nbsp; \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e, \u0447\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u043e\u0436\u0435 \u043d\u0430 Go, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043c\u043e\u0447\u044c \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438&nbsp;\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u044d\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u0433\u0434\u0435 \u043f\u0430\u0434\u0430\u0435\u0442 \u0438 \u043a\u0430\u043a \u043f\u0430\u0434\u0430\u0435\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u044b \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0435 \u043e\u0442\u0447\u0435\u0442\u044b. \u0423 \u043d\u0430\u0441 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 <a href=\"https:\/\/docs.qameta.io\/allure-testops\/\">allure-\u0441\u0435\u0440\u0432\u0435\u0440<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 Allure.<\/p>\n<p><a class=\"anchor\" name=\"2\" id=\"2\"><\/a><\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 Allure-go \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/h2>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 Allure \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430 Go, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0442 (\u043f\u043e\u043a\u0430 \u043d\u0435\u0442).<\/p>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u044f \u043d\u0430\u0448\u043b\u0430 \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0435&nbsp;\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 Allure \u0441 Go<\/p>\n<p><a href=\"https:\/\/github.com\/GabbyyLS\/allure-go-common\">Allure-go-common<\/a> \u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 6 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434. \u0418 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u0430\u0441\u044c, \u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0433\u043e;  \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u0430\u043a\u0430\u044f-\u043b\u0438\u0431\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f.<\/p>\n<p><a href=\"https:\/\/github.com\/dailymotion\/allure-go\">Allure-go<\/a> \u2014 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430, \u0435\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441 \u043c\u043d\u043e\u0433\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u043b\u0430 allure-go \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c.<\/p>\n<p><a class=\"anchor\" name=\"3\" id=\"3\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 Allure-go<\/h2>\n<details class=\"spoiler\">\n<summary>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 java<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e, \u043a\u0430\u043a \u044f, \u043f\u0440\u0438\u0448\u0435\u043b \u0438\u0437 Java, \u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e&nbsp;\u043e\u0442\u043b\u0438\u0447\u0438\u044f. <\/p>\n<p>\u041f\u0440\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>Java \u2014 \u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u041a\u043e\u0434 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 src\/main\/, \u0442\u0435\u0441\u0442\u044b \u043b\u0435\u0436\u0430\u0442 \u0432 src\/test\/<\/p>\n<\/li>\n<li>\n<p>Go \u2014 \u043d\u0435\u0442 \u0447\u0435\u0442\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438. \u042e\u043d\u0438\u0442 \u0442\u0435\u0441\u0442\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u043b\u0435\u0436\u0430\u0442 \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c, \u0442.\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0430\u043a\u0435\u0442 sender.go \u0438 \u0440\u044f\u0434\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u043f\u0430\u043f\u043a\u0435 sender_test.go (\u043f\u043e \u043f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u0443 _test \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438)<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0435\u0441\u0442 \u043d\u0430 Java + Allure<\/p>\n<p>\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @Test<\/p>\n<pre><code class=\"java\">@Test func sendTransactionSucc\u0435edTest() {     String clientID = config.GetClientID();     String trxID = apiSteps.SendTransaction(clientID);     Transaction trx = dbSteps.GetTransactionByID(trxID);     assertSteps.CheckTransactionFields(trx); }<\/code><\/pre>\n<p>\u0412 \u0448\u0430\u0433\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @Step<\/p>\n<pre><code class=\"java\">@Step(\u201cSend transaction with clientID \\\\\\\\d+\u201c) func (Steps s) SendTransaction(String clientID) {     String msg = parseJSON();     msg.SetClient(clientID);     s.trxClient.Send(msg); }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 Go \u043d\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439, \u043a\u0430\u043a \u0432 Java. \u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0448\u0430\u0433, \u0442\u0443\u0442 \u043d\u0435 \u043e\u0431\u043e\u0439\u0434\u0435\u0448\u044c\u0441\u044f @step.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0442\u0430\u043a\u0430\u044f \u0436\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 allure.step. \u0412\u043d\u0443\u0442\u0440\u0438 step-a \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 allure.description, \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f allure.Action \u2014 \u0433\u0434\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c.<\/p>\n<pre><code class=\"go\">func doSomething(){     allure.Step(allure.Description(\"Something\"), allure.Action(func(){         doSomethingNested()     })) }<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0422\u0435\u0441\u0442\u0430 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c allure.Test:<\/p>\n<pre><code class=\"go\">func TestPassedExample(t *testing.T) {     allure.Test(t,                 allure.Description(\"This is a test to show allure implementation with a passing test\"),                 allure.Action(func() {                     s := \"Hello world\"                     if len(s) == 0 {                       \tt.Errorf(\"Expected 'hello world' string, but got %s \", s)                     }                 })) }<\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/dailymotion\/allure-go\/tree\/master\/example\">\u0442\u0443\u0442<\/a>. <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0438\u0448\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u043c\u043e\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p><a class=\"anchor\" name=\"4\" id=\"4\"><\/a><\/p>\n<h2>Assertion-\u044b \u0432 go, \u0432\u044b\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p>\u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e assertion-\u044b. <strong>Assertion-\u044b<\/strong> \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438. \u0424\u0443\u043d\u043a\u0446\u0438\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0432 \u043a\u0430\u043a\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443\u043f\u0430\u043b \u0442\u0435\u0441\u0442 \u0438 \u0441 \u043a\u0430\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<p>\u042f \u043d\u0435 \u0441\u0442\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438 \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u0441\u0430\u043c \u0442\u0435\u0441\u0442.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435, \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0430\u0436\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 assertion-\u0430 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u044d\u0442\u043e <strong>\u043d\u0435\u044f\u0432\u043d\u044b\u0435 (\u0443\u043c\u043d\u044b\u0435) \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/strong> \u2014 \u043a\u043e\u0433\u0434\u0430&nbsp;\u043e\u0436\u0438\u0434\u0430\u0435\u0448\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 Go, Allure <\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0423\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c&nbsp;\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445, \u0441\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0432\u043e\u0434 \u0432\u0441\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 (soft assertion)<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 assertion \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u043e \u044d\u0442\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>General info<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>C\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c  \u0441 Go, Allure<\/p>\n<\/td>\n<td>\n<p>\u0423\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, soft assertion<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p>Go \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u043a\u0430<\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0435\u0440\u0436\u043a\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438 \u0442\u0435\u0442\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/stretchr\/testify\">testify<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438 \u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u043c\u043e\u043a\u043e\u0432.<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/labix.org\/gocheck\">gocheck<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438. \u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 go test. \u0418\u043c\u0435\u0435\u0442 \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441 testify.<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/onsi.github.io\/gomega\/\">gomega<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438. \u0410\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 BDD \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c Ginkgo. \u041d\u043e \u043c\u043e\u0436\u0435\u0442 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438. <\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/google\/go-cmp\">gocmp<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0411\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u0430\u044f \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430  \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 reflect.DeepEqual<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/maxatome\/go-testdeep\">go-testdeep<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0438\u0431\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043d \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0438\u0437 Test::Deep perl module<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u0437 \u0432\u0441\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u043d\u043e\u0439 \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 <a href=\"https:\/\/onsi.github.io\/gomega\/\"><strong>Gomeg\u0430<\/strong><\/a> \u2014 \u0447\u0435\u0442\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438, \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438, \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 eventually \u0438 consistently, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0443\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435, \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e BDD-\u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f go \u0432\u043c\u0435\u0441\u0442\u043e Allure. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440. <a href=\"https:\/\/onsi.github.io\/ginkgo\/\">Gingko<\/a>, <a href=\"http:\/\/goconvey.co\/\">Goconvey<\/a>, <a href=\"https:\/\/github.com\/franela\/goblin\">Goblin<\/a>. \u0418 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Allure, \u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0438\u0445 \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c. \u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0441\u0432\u043e\u0438\u0445 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0442\u044c\u0438 \u0441\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/bmuschko.com\/blog\/go-testing-frameworks\/\">https:\/\/bmuschko.com\/blog\/go-testing-frameworks\/<\/a><\/p>\n<p><a href=\"https:\/\/knapsackpro.com\/testing_frameworks\/alternatives_to\/testing\">https:\/\/knapsackpro.com\/testing_frameworks\/alternatives_to\/testing<\/a><\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"5\" id=\"5\"><\/a><\/p>\n<h2>O gomega<\/h2>\n<p>\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 <a href=\"https:\/\/onsi.github.io\/gomega\/\">Gomega<\/a>?<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 assertion-a<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>\u03a9<\/strong>:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"go\">\u03a9(ACTUAL).Should(Equal(EXPECTED)) \u03a9(ACTUAL).ShouldNot(Equal(EXPECTED))<\/code><\/pre>\n<ul>\n<li>\n<p>\u0418\u043b\u0438 <strong>Expect<\/strong>:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"go\">Expect(ACTUAL).To(Equal(EXPECTED)) Expect(ACTUAL).NotTo(Equal(EXPECTED)) Expect(ACTUAL).ToNot(Equal(EXPECTED))<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0442\u0435\u0441\u0442\u0435 \u0441 Allure:<\/p>\n<pre><code class=\"go\">allure.Test(t, allure.Action(func() {     allure.Step(allure.Description(\"Something\"), allure.Action(func() {       gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), \"Text error\")     })) }))<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 <strong>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0430\u0441\u0441\u0435\u0440\u0448\u0435\u043d\u044b<\/strong> (\u0443\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f) \u0432 Gomega:<\/p>\n<pre><code>Eventually(func() []int {         return thing.SliceImMonitoring }, TIMEOUT, POLLING_INTERVAL).Should(HaveLen(2))<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <strong>eventually<\/strong> \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 (POLLING_INTERVAL), \u043f\u043e\u043a\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0438\u043b\u0438 \u043d\u0435 \u0438\u0441\u0442\u0435\u0447\u0435\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442.<\/p>\n<p>\u0423\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c&nbsp;\u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0431\u0430\u0437\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. (\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445&#187; \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440)<\/p>\n<p><strong>Consistently<\/strong> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 c \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439.<\/p>\n<p>\u0423\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0431\u0430\u0437\u0435 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u0438\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 10 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"go\">Consistently(func() []int {         return thing.MemoryUsage() }).Should(BeNumerically(\"&lt;\", 10))<\/code><\/pre>\n<p><a class=\"anchor\" name=\"6\" id=\"6\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c gomega \u0441 allure<\/h2>\n<p>Gomega \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 BDD \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c Gingko (\u043d\u0430\u043c \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u043d\u043e \u0432 \u0434\u043e\u043a\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043d\u0438\u043c, \u0438 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430 allure \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a).<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u0434\u043b\u044f Gingko \u043d\u0430\u0434\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0442\u0435\u0441\u0442-\u0441\u044c\u044e\u0442\u0430:<\/p>\n<pre><code class=\"go\">gomega.RegisterFailHandler(ginkgo.Fail)<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 gomega assertion&nbsp;\u0444\u0435\u0439\u043b\u0438\u0442\u0441\u044f, gomega \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>GomegaFailHandler<\/code><strong> <\/strong>(\u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e&nbsp;<code>gomega.RegisterFailHandler()<\/code>)<\/p>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b Allure, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 FailHandler.<\/p>\n<p><strong>\u041a\u0430\u043a\u0430\u044f \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/strong>. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 gomega \u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 gomega c \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>RegisterTestingT<\/code>, \u043a\u0430\u043a \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435<\/p>\n<pre><code class=\"go\">func TestFarmHasCow(t *testing.T) {     gomega.RegisterTestingT(t)      f := farm.New([]string{\"Cow\", \"Horse\"})     gomega.Expect(f.HasCow()).To(BeTrue(), \"Farm should have cow\") }<\/code><\/pre>\n<p><strong>\u0418\u0442\u043e\u0433<\/strong>: \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c, \u0447\u0442\u043e \u0432 Allure \u043e\u0442\u0447\u0435\u0442\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0442 gomega. \u0412\u044b\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u043e\u0442\u0447\u0435\u0442 \u0441 \u0442\u0435\u0441\u0442\u043e\u043c, \u0447\u0442\u043e \u0448\u0430\u0433 \u0437\u0430\u0444\u0435\u0439\u043b\u0438\u043b\u0441\u044f (\u043a\u0430\u043a \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435), \u043d\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bfa\/dff\/5a4\/bfadff5a400ae3c9a16d18d176d30ec3.png\" width=\"2266\" height=\"852\"><figcaption><\/figcaption><\/figure>\n<p><strong>\u041a\u0430\u043a \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c<\/strong>. \u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e wrapper, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0444\u0435\u0439\u043b\u0435,&nbsp;\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043c\u0435\u0442\u043e\u0434 <code>allure.Fail<\/code> (\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>allure.error<\/code>, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u0442\u0435\u0441\u0442\u0430 \u2014 fail, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u043e\u0448\u0438\u0431\u043a\u0438)<\/p>\n<pre><code class=\"go\">\/\/\u043d\u0430\u0448 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 wrapper func BuildTestingTGomegaFailWrapper(t *testing.T) *types.GomegaFailWrapper {      \/\/\u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fail             fail := func(message string, callerSkip ...int) {          \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 allure.fail \u0434\u043b\u044f \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043e\u0442\u0447\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438         allure.Fail(errors.New(message))              t.Fatalf(\"\\\\n%s %s\", message, debug.Stack())     }     return &amp;types.GomegaFailWrapper{         Fail:&nbsp; &nbsp;     fail,         TWithHelper: t,     } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u043c \u0442\u0435\u0441\u0442\u0430, \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f gomega \u0438 \u0432 <code>FailHandler<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430\u0448 <code>wrapper.BuildTestingTGomegaFailWrapper(t).Fail<\/code><\/p>\n<pre><code class=\"go\">func SetGomegaParameters(t *testing.T) { \t\t\/\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f T \u0432 gomega, \u0447\u0442\u043e\u0431 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c t \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     gomega.RegisterTestingT(t)  \t\t\/\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430     gomega.RegisterFailHandler(wrapper.BuildTestingTGomegaFailWrapper(t).Fail) }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 \u043e\u0442\u0447\u0435\u0442\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/521\/75f\/620\/52175f620f03eae491c4c7cd24ae2b1c.png\" width=\"2270\" height=\"1438\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0435\u0449\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c, \u0447\u0442\u043e Gomega \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0443\u0434\u043e\u0431\u043d\u0430 \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0437\u0434\u0435 <code>testing.T<\/code>.<\/p>\n<p><a class=\"anchor\" name=\"7\" id=\"7\"><\/a><\/p>\n<h2>\u041f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0442\u0435\u0441\u0442\u044b<\/h2>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0431\u044b\u043b \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043a\u0430\u043a \u0432\u044b\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 Go \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432. \u0412 \u0438\u0442\u043e\u0433\u0435 \u0432\u043e\u0442 \u043a\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c:<\/p>\n<figure class=\"float full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d8\/a72\/337\/2d8a72337c448c5107e006c3f97f5a6c.png\" width=\"740\" height=\"730\"><figcaption><\/figcaption><\/figure>\n<ul>\n<li>\n<p><em>api<\/em> \u2014 \u043f\u0430\u043a\u0435\u0442\u044b \u0441 proto-\u0444\u0430\u0439\u043b\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p><em>pkg<\/em> \u2014 \u043f\u0430\u043a\u0435\u0442, \u0433\u0434\u0435 \u043b\u0435\u0436\u0438\u0442 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 (\u0448\u0430\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u0430 \u0438 assertion steps)<\/p>\n<ul>\n<li>\n<p>database \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439<\/p>\n<\/li>\n<li>\n<p><em>grpc<\/em> \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 \u043f\u043e grpc<\/p>\n<\/li>\n<li>\n<p><em>overall<\/em> \u2014 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0435 \u0448\u0430\u0433\u0438 (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u043b\u0438\u043d\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0448\u0430\u0433\u043e\u0432, \u0438 \u043e\u043d\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442\u0441\u044f, \u0438 \u044d\u0442\u043e \u043c\u0435\u0448\u0430\u0435\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u0442\u0435\u0441\u0442\u0430, \u0442\u043e \u0432\u044b\u043d\u043e\u0441\u0438\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u0438\u0445 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0448\u0430\u0433\u043e\u0432 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0448\u0430\u0433 \u0432 \u044d\u0442\u043e\u0442 \u043f\u0430\u043a\u0435\u0442)<\/p>\n<\/li>\n<li>\n<p><em>clients<\/em> \u2014 \u0432\u043d\u0443\u0442\u0440\u0438 \u044d\u0442\u0438\u0445 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0439 \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043a\u0443\u0434\u0430-\u0442\u043e \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u044d\u0442\u043e \u043a\u043b\u0438\u0435\u043d\u0442. \u041a\u043b\u0438\u0435\u043d\u0442 \u0431\u0435\u0440\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p><em>di<\/em> \u2014 \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 dependency injection, \u0447\u0442\u043e\u0431 \u043d\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/p>\n<\/li>\n<li>\n<p><em>config<\/em> \u2014 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0430<\/p>\n<\/li>\n<li>\n<p><em>assertion<\/em> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 steps, \u0437\u043d\u0430\u0447\u0438\u0442 \u0442\u0430\u043c \u0448\u0430\u0433\u0438 \u0442\u0435\u0441\u0442\u0430 (allure.step), \u0435\u0441\u043b\u0438 \u0431\u0435\u0437 steps, \u0442\u043e \u0442\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043d\u0430\u0440\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6d3\/c99\/f33\/6d3c99f3366ff0aa8ff3acb865b32762.png\" width=\"454\" height=\"294\"><figcaption><\/figcaption><\/figure>\n<\/li>\n<li>\n<p><em>suites<\/em> \u2014 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u0438 \u0442\u0435\u0441\u0442\u044b, \u0441\u043f\u0438\u0441\u043e\u043a \u0438 \u0432\u044b\u0437\u043e\u0432 \u0448\u0430\u0433\u043e\u0432 \u0438\u0437 pkg (\u043f\u0440\u0438\u043c\u0435\u0440 \u0443\u043a\u0430\u0437\u0430\u043d \u043d\u0438\u0436\u0435)<\/p>\n<\/li>\n<li>\n<p><em>testdata<\/em> \u2014 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445<\/p>\n<\/li>\n<li>\n<p><em>tests<\/em> \u2014 \u0442\u0443\u0442 \u043b\u0435\u0436\u0430\u0442 \u0444\u0430\u0439\u043b\u044b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0435\u0436\u0430\u0442 \u0432 suites<\/p>\n<ul>\n<li>\n<p><em>runner_test.go<\/em> \u2014 \u0440\u0430\u0437\u043d\u044b\u0435 runner-\u044b \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p><em>main_test.go<\/em> \u2014 \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043b\u0435\u0436\u0438\u0442 func TestMain(m *testing.M) {} \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a \u0442\u0435\u0441\u0442\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e m.Run<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><em>tmp<\/em> \u2014 \u043f\u0430\u043f\u043a\u0430 \u0434\u043b\u044f \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 allure \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 suite<\/strong>:<\/p>\n<p>\u0422\u0443\u0442 \u0434\u0432\u0430 \u0442\u0435\u0441\u0442\u0430. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0443\u043a\u0430\u0437\u0430\u043d\u043e\u0435 \u0432 <code>t.Run<\/code>, \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432  allure-\u043e\u0442\u0447\u0435\u0442\u0435 c \u043d\u0438\u0436\u043d\u0438\u043c \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u0438\u0432\u0430\u043d\u0438\u0435\u043c. \u041b\u0438\u0431\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c <code>allure.Name<\/code> \u0432 \u0442\u0435\u0441\u0442\u0435.<\/p>\n<pre><code class=\"go\">func TestRequest(t *testing.T, countryType string) {     t.Run(\"Test1: \u0423\u0441\u043f\u0435\u0448\u043d\u0430\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\", func(t *testing.T) {         allure.Test(t, allure.Action(func() {           \tSendRequestSucc\u0435ed(t)         }))     })     t.Run(\"Test2: \u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439\", func(t *testing.T) {         allure.Test(t, allure.Action(func() {           \tSendingResuestWithErrorTest(t)         })) })<\/code><\/pre>\n<p><strong>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0435\u0441\u0442:<\/strong><\/p>\n<pre><code class=\"go\">func SendRequestSucc\u0435ed(c *di.Components, t *testing.T) { \/\/ di c \u0443\u0436\u0435 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438     common.SetGomegaParameters(t) \/\/ \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0435 gomega \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432     clientID := c.Config.GetClientID()     reqD := c.apiSteps.SendRequest(clientID) \/\/ \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     req := c.DBSteps.GetRequestByID(reqID) \/\/ \u0437\u0430\u043f\u0440\u043e\u0441 \u0438\u0437 \u0431\u0430\u0437\u044b     c.assertSteps.CheckRequestFields(req) \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u043e\u043b\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 }<\/code><\/pre>\n<p><strong>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 \u0448\u0430\u0433?<\/strong> \u042d\u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0432\u0438\u0434\u0430 <code>allure.Step(allure.Description(), allure.Action(func() )<\/code><\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0448\u0430\u0433\u0430 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u043e\u0439 allure-go<\/p>\n<pre><code class=\"go\">func (s *Steps) SendRequest(clientID string) {     allure.Step( \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0448\u0430\u0433\u0430       allure.Description( \/\/ \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0448\u0430\u0433\u0430           fmt.Sprintf(\"Send request with clientID: %s\", clientID)),       allure.Action(func() { \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0448\u0430\u0433\u0430         \tmsg := parseJSON() \/\/ \u0431\u0435\u0440\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430         \tmsg.SetClient(clientID)         \ts.reqClient.Send(msg)     })) }<\/code><\/pre>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440 Assertion \u0448\u0430\u0433\u0430<\/strong><\/p>\n<pre><code class=\"go\">func CheckRequestFields(req Request, expectedStatus req.Status, statusReason req.StatusReason){   \tallure.Step(       allure.Description(\"Check fields of request in db\"),        allure.Action(func() {       \t\tgomega.Expect(trx.Status).Should(gomega.Equal(expectedStatus), \"Status was not expected\")       \t\tgomega.Expect(trx.StatusReason).Should(gomega.Equal(statusReason), \"Status reason was not expected\") }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0448\u0430\u0433\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u0448\u0430\u0433\u0438. \u0412\u0441\u0435 \u044d\u0442\u043e \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u0447\u0435\u0442, \u0438 \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u0447\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u0430 \u0432 allure-\u043e\u0442\u0447\u0435\u0442\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3a6\/add\/bd2\/3a6addbd20a99013baa0cd461e5e98c5.png\" width=\"2192\" height=\"1602\"><figcaption><\/figcaption><\/figure>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c attachment \u0432 \u0432\u0438\u0434\u0435 json \u0438\u043b\u0438 \u0442\u0435\u043a\u0441\u0442\u0430 (\u043a\u0430\u043a \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435 \u0432\u044b\u0448\u0435 \u2014 \u0432 Actual fields)<\/p>\n<pre><code class=\"go\">err = allure.AddAttachment(name, allure.*ApplicationJson*, []byte(fmt.Sprintf(\"%+v\", string(aJSON)))) err := allure.AddAttachment(name, allure.*TextPlain*, []byte(fmt.Sprintf(\"%+v\", a)))<\/code><\/pre>\n<hr>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u0442 \u0447\u0430\u0441\u0442\u044c \u0432\u0433\u043b\u0443\u0431\u044c, \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445, rest-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c, \u043a\u043e\u043d\u0444\u0438\u0433\u0430\u043c\u0438, di \u0438 gitlab. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0438 \u0435\u0449\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0437\u0430\u0441\u043a\u0443\u0447\u0430\u043b\u0438, \u0437\u0430\u043f\u0430\u0441\u0438\u0442\u0435\u0441\u044c \u0447\u0430\u0439\u043a\u043e\u043c, \u043a\u043e\u0444\u0435\u0439\u043a\u043e\u043c)<\/p>\n<hr>\n<p><a class=\"anchor\" name=\"8\" id=\"8\"><\/a><\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 REST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438<\/h2>\n<p>\u0414\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f REST-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/github.com\/go-resty\/resty\">go-resty<\/a><\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430\u0434\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c resty \u043a\u043b\u0438\u0435\u043d\u0442<\/p>\n<pre><code class=\"go\">client := resty.New() authJSON, err := json.Marshal(authRequest) \/\/ \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 Post resp, err := client.R(). \t\tSetHeader(\"Content-Type\", \"application\/json\").     SetBody(authJSON). \/\/\u0442\u0435\u043b\u043e     Post(c.url) \/\/\u0443\u0440\u043b \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Client<\/p>\n<pre><code class=\"go\">type Client struct {   \tlog *log.CtxLogger   \t*resty.Client   \turl string }<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043b\u043e\u0433 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433)<\/p>\n<pre><code class=\"go\">func NewClient(l log.Service, conf config.APIConfigResult) *Client {     return &amp;Client{         Client: resty.New(),          log: l.NewPrefix(\"\u0421lient\"),         url: conf.Auth.URL     } }<\/code><\/pre>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/p>\n<pre><code class=\"go\">func (c *Client) Send(req Request) Response {     reqJSON, err := json.Marshal(req) \/\/\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c json \u0438\u0437 \u043e\u0431\u044a\u0435\u043a\u0442\u0430     gomega.Expect(err).ShouldNot(gomega.HaveOccurred())     resp, err := c.R().         SetHeader(\"Content-Type\", \"application\/json\").         SetBody(reqJSON).         Post(c.url) \/\/ \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0442\u0438\u043f\u044b GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS     gomega.Expect(err).ShouldNot(gomega.HaveOccurred())     c.log.InfofText(\"Response\", resp.String())     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0443\u0441 200     gomega.Expect(resp.StatusCode()).Should(gomega.Equal(http.*StatusOK*))      resp := Response{}     err = json.Unmarshal(resp.Body(), &amp;resp) \/\/ \u0438\u0437&nbsp; json \u0434\u0435\u043b\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442&nbsp;      gomega.Expect(err).ShouldNot(gomega.HaveOccurred())     return resp \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0442\u0432\u0435\u0442\u0430 }<\/code><\/pre>\n<p><a class=\"anchor\" name=\"9\" id=\"9\"><\/a><\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0431\u0430\u0437\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 database\/sql. \u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0440\u043e\u043a\u0442\u0435 postgresql.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 pq.<\/p>\n<pre><code class=\"go\">import (     \"database\/sql\"     _ \"github.com\/lib\/pq\" )<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>Client<\/code> \u0441 *sql.DB<\/p>\n<pre><code class=\"go\">type Client struct {     *sql.DB     log *log.CtxLogger }<\/code><\/pre>\n<p>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/p>\n<pre><code class=\"go\">func NewClient(conf config.APIConfigResult, l log.Service) *Client {         \/\/\u0431\u0435\u0440\u0435\u043c \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0430&nbsp; \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b&nbsp; \u0434\u043b\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445         dbConf := conf.DB         \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a         dbURL := fmt.Sprintf(\"postgres:\/\/%v:%v@%v:%v\/%v\", dbConf.Username, dbConf.Password, dbConf.Host, dbConf.Port, dbConf.DBName)         \/\/\u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435         db, err := sql.Open(\"postgres\", dbURL)         gomega.Expect(err).ShouldNot(gomega.HaveOccurred())         return &amp;Client{DB: db, log: l.NewPrefix(\"db.client.cardmanager\")} }<\/code><\/pre>\n<p>\u0427\u0442\u043e\u0431 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u0431\u0430\u0437\u0443 (\u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u0443\u043c\u043d\u044b\u043c \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0435\u043c, \u0436\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435)<\/p>\n<pre><code class=\"go\">\/\/select \u0437\u0430\u043f\u0440\u043e\u0441 const selectCardInfoByClient = \"Select status from cards where client_id = $1\"  func (c *Client) GetCardStatus(clientID string) (status string) {     gomega.Eventually(func() error {         \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440         err := c.QueryRow(selectCardInfoByClient, clientID).          Scan(&amp;status) \/\/ \u043e\u0436\u0438\u0434\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441         return err     }, \"60s\", \"1s\").     \/\/\u0435\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0430, \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0435\u0449\u0435 \u0440\u0430\u0437; \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435\u0442, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441   \t\t\tShould(gomega.Succeed(), fmt.Sprintf(\"Not found card by client: %s in db\", clientID))      c.log.InfofJSON(\"Card info\", status)     return status }<\/code><\/pre>\n<p><a class=\"anchor\" name=\"10\" id=\"10\"><\/a><\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c<\/h2>\n<p>\u0412\u0441\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0423 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0432\u043e\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 yaml \u0444\u0430\u0439\u043b\u0430\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/904\/f97\/748\/904f97748fdd208509844dcfbdaa88f0.png\" width=\"740\" height=\"130\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0445\u0440\u0430\u043d\u044f\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u0431\u0430\u0437\u043e\u0439, \u0443\u0440\u043b\u044b, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u0442.\u0434<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 yaml \u0444\u0430\u0439\u043b\u0430.<\/p>\n<pre><code class=\"yaml\">userService: \turl: \"&lt;https:\/\/testurl.org&gt;\"  dbPro\u0441:   host: dbhost.ru   username: user   dbname: userdb   password: pass   port: 5432<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442<\/p>\n<pre><code class=\"go\">type DB struct {     Host &nbsp; &nbsp; string `yaml:\"host\"`     Port &nbsp; &nbsp; string `yaml:\"port\"`         DBName &nbsp; string `yaml:\"dbname\"`     Username string `yaml:\"username\"`     Password Secret `yaml:\"password\"` }  type Client struct {           \tURL string `yaml:\"url\"` }<\/code><\/pre>\n<p>\u0418 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430<\/p>\n<pre><code class=\"go\">type APIConfig struct {     MainConfig &nbsp; &nbsp; &nbsp; `yaml:\"main\"`     Logger &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `yaml:\"logger\" validate:\"required\"`     DBProc &nbsp; &nbsp; \t\t\t  DB &nbsp; &nbsp; &nbsp; &nbsp; `yaml:\"dbPro\u0441\" validate:\"required\"`     UserService &nbsp; &nbsp; &nbsp; Client &nbsp; &nbsp; `yaml:\"clearing\" validate:\"required\"` }  \/\/\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0444\u0438\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u0437\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c type APIConfigResult struct {     Logger     DBProcessing &nbsp; &nbsp; DB     UserService&nbsp; &nbsp; &nbsp; Client }<\/code><\/pre>\n<p>\u0412 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f env \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"go\">const (     LocalEnv  string = \"local\"     DevEnv    string = \"dev\"     StableEnv string = \"stable\" )  func getEnv() (string, error) {    if env := os.Getenv(Env); len(env) != 0 {        switch env {        caseDevEnv:          \treturn DevEnv, nil        caseLocalEnv:          \treturn LocalEnv, nil        caseStableEnv:          \treturn StableEnv, nil        }    }    return \"\", fmt.Errorf(\"cannot parse env variable\") }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 APIConfigResult \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 yaml \u043a\u043e\u043d\u0444\u0438\u0433\u0430<\/p>\n<pre><code class=\"go\">func NewAPIConfig() (APIConfigResult, error) {     var (         c&nbsp; &nbsp; &nbsp; APIConfig         result APIConfigResult         err&nbsp; &nbsp; error     )   \tc.MainConfig.Env, err = getEnv() \/\/\/\u0432\u044b\u0431\u043e\u0440 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f      if err != nil {       \treturn APIConfigResult{}, err     }      var confPath string      switch c.MainConfig.Env { \/\/\u0432\u044b\u0431\u043e\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f         case StableEnv:       \t\t\tconfPath = \"config-stable.yml\"         case DevEnv:         \t\tconfPath = \"config-dev.yml\"         default:         \t\tconfPath = \"config-local.yml\"     }  \t  \/\/\u0447\u0442\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 'c' \u043e\u0431\u044a\u0435\u043a\u0442     if err := ReadConfig(confPath, &amp;amp;c); err != nil {       \treturn result, errors.Wrap(err, `failed to read config file`)     }      result.Logger = c.Logger     result.DBProcessing = c.DBProcessing     result.UserService = c.UserService      return result, validator.New().Struct(c)  } func ReadConfig(configPath string, config interface{}) error {     if configPath == `` {      \t return fmt.Errorf(no config path)     }   \t\/\/\u0447\u0442\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430     configBytes, err := ioutil.ReadFile(configPath)       if err != nil {     \t  return errors.Wrap(err, failed to read config file)     }   \t\/\/\u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f     if err = yaml.Unmarshal(configBytes, config); err != nil {        \t return errors.Wrap(err, failed to unmarshal yaml config)     }     return nil }<\/code><\/pre>\n<p>\u0412\u044b\u0448\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 REST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438&#187;  \u0431\u044b\u043b \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>APIConfigResult<\/code>  \u0432 <code>NewClient <\/code><\/p>\n<p><a class=\"anchor\" name=\"11\" id=\"11\"><\/a><\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 dependency injection<\/h2>\n<p>\u041f\u0440\u043e dependency injection \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0442\u0435\u0439, \u0432\u043e\u0442 <a href=\"https:\/\/habr.com\/ru\/company\/vivid_money\/blog\/531822\/\">\u0442\u0443\u0442<\/a> \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0435, \u0437\u0430\u0447\u0435\u043c \u043e\u043d \u043d\u0443\u0436\u0435\u043d, \u0438 \u043a\u0430\u043a \u0441 \u043d\u0438\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 Go.<\/p>\n<p>\u0412 \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e dependency injection, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435. A c \u043f\u043e\u043c\u043e\u0449\u044c\u044e di \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c, \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u044d\u0442\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431 \u043d\u0435 \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0441\u0442 \u043a\u0443\u0447\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>\u0414\u043b\u044f dependency&nbsp;injection&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 &#171;<a href=\"https:\/\/pkg.go.dev\/go.uber.org\/dig#section-readme\">go.uber.org\/dig<\/a>&#187; <\/p>\n<p><strong>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/strong><\/p>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a DI \u0441\u0442\u0440\u043e\u0438\u0442 \u0433\u0440\u0430\u0444 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u00ab\u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u043e\u0432\u00bb, \u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u044b \u0435\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442\u0435, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0430\u0448\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432.<\/p>\n<pre><code class=\"go\">c := common.Before(t)<\/code><\/pre>\n<p>\u0412 \u043d\u0435\u0439 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0434\u043b\u044f&nbsp;dependency injection.<\/p>\n<pre><code class=\"go\">func Before(t *testing.T) *di.Components {     var c *di.Components     allure.BeforeTest(t,                       allure.Description(\"Init Components\"),                       allure.Action(func() {                         \tSetGomegaParameters(t)                         \tvar err error                         \t\/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430                         \tc, err = di.BuildContainer()                         \tgomega.Expect(err).Should(gomega.Not(gomega.HaveOccurred()),                                                   fmt.Sprintf(\"unable to build container: %v\", dig.RootCause(err)))                       })) \t\treturn c \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b } <\/code><\/pre>\n<p>\u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 buildContainer<\/p>\n<pre><code class=\"go\">\/\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u043d\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 type Components struct {     DBProcessing&nbsp; &nbsp; &nbsp; &nbsp; *processing.Client     UserService &nbsp; &nbsp; &nbsp; &nbsp; *user.Client     Logger log.Service     Config config.APIConfigResult }  func BuildContainer() (*Components, error) {     c := dig.New() \/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430     servicesConstructors := []interface{}{ &nbsp;       \/\/\u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432       config.NewAPIConfig,       log.NewLoggerService,       processing.NewClient,       user.NewClient,     } \/\/\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043d\u0438\u0436\u0435 ...<\/code><\/pre>\n<p>\u0412 dig \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 provide \u0438 invoke. \u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u043e\u0432, \u0432\u0442\u043e\u0440\u0430\u044f \u2014 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.<\/p>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 Provide, \u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440.<\/p>\n<pre><code class=\"go\">... \t\t\/\/\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435      for _, service := range servicesConstructors {       \t\/\/\u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0432 di         err := c.Provide(service)         if err != nil {           return nil, err         }     }      comps, compsErr := initComponents(c) \/\/\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f     if compsErr != nil {         return nil, compsErr     }     return comps, nil }<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 initComponents \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f Invoke. Dig \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c, \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445 \u0442\u0438\u043f\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439.  \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0442\u0438\u043f \u0438\u043b\u0438 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435, \u0432\u044b\u0437\u043e\u0432 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<pre><code class=\"go\">func initComponents(c *dig.Container) (*Components, error) {     var err error     t := Components{}     err = c.Invoke(func( \/\/ \u0432\u044b\u0437\u043e\u0432 \u0441 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438         processingClient *processing.Client,          userService *user.Client,         logger log.Service,         conf config.APIConfigResult,     ) {         t.DBProcessing = processingClient         t.Config = conf         t.Logger = logger         t.UserService = userService     })     if err != nil {       \treturn nil, err     }      return &amp;amp;t, nil }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u0442\u0430\u043a: <code>\u0441.Config<\/code>, <code>\u0441.Logger<\/code> \u0438 \u0442.\u0434.<\/p>\n<p><a class=\"anchor\" name=\"12\" id=\"12\"><\/a><\/p>\n<h2>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f  \u043e\u0442\u0447\u0435\u0442\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u0432 Gitlab-CI<\/h2>\n<h3>Allure-report \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e<\/h3>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c Allure \u043e\u0442\u0447\u0435\u0442 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u043d\u0443\u0436\u043d\u043e:<\/p>\n<ol>\n<li>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c <a href=\"https:\/\/docs.qameta.io\/allure\/#_reporting\">Allure<\/a><\/p>\n<pre><code class=\"bash\">brew install allure \/\/on mac os<\/code><\/pre>\n<\/li>\n<li>\n<p>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c ALLURE_RESULTS_PATH \u0432 environments&nbsp;\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440. \u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0433\u043e\u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432<\/p>\n<pre><code>ALLURE_RESULTS_PATH=\/Users\/user\/IdeaProjects\/integration-tests\/tmp\/<\/code><\/pre>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 environment \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f77\/b29\/785\/f77b29785d48f667e3f7dbe0eebc1b82.png\" width=\"1498\" height=\"312\"><figcaption><\/figcaption><\/figure>\n<\/li>\n<li>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0447\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u0440\u043e\u0433\u043e\u043d\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 allure generate, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 \u043f\u0443\u0442\u044c \u043a \u043f\u0430\u043f\u043a\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438(<a href=\"https:\/\/github.com\/dailymotion\/allure-go\/tree\/v2.0#using\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/a>).<\/p>\n<pre><code class=\"bash\">allure generate \/Users\/user\/IdeaProjects\/integration-tests\/tmp\/allure-results --clean<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>\u0418 \u0432 \u043f\u0430\u043f\u043a\u0435 allure-report \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c index.html \u0441 \u043e\u0442\u0447\u0435\u0442\u043e\u043c.<\/p>\n<figure class=\"float full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f11\/f5a\/55f\/f11f5a55f8d4a82283c30f0ad96f6972.png\" width=\"752\" height=\"412\"><figcaption><\/figcaption><\/figure>\n<h3>Gitlab-\u0441i<\/h3>\n<p>\u0422\u0435\u0441\u0442\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u0432 \u0434\u043e\u043a\u0435\u0440\u0435 \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u0441\u0442\u0435\u043d\u0434\u0430, \u0433\u0434\u0435 \u0443\u0436\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u044b \u0432\u0441\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u044b\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u043d\u0430 allure-\u0441\u0435\u0440\u0432\u0435\u0440. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043f\u043e scheduler \u0432 gitlab-ci.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/23a\/346\/95d\/23a34695d94e84cc379bcaab126adb52.png\" alt=\"Runner \u0432 Scheduler\" title=\"Runner \u0432 Scheduler\" width=\"1600\" height=\"228\"><figcaption>Runner \u0432 Scheduler<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/663\/dff\/7bd\/663dff7bddcb3e45899a3a34ae8f4837.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 job-\u044b \u0432 .gitlab-ci.yml\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 job-\u044b \u0432 .gitlab-ci.yml\" width=\"1600\" height=\"416\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 job-\u044b \u0432 .gitlab-ci.yml<\/figcaption><\/figure>\n<p>\u0412 gitlab-ci.yml&nbsp; \u0432 job \u0432 before-script \u0434\u043b\u044f&nbsp;\u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c allurectl \u0438\u0437 github <\/p>\n<pre><code class=\"bash\">- wget &lt;https:\/\/github.com\/allure-framework\/allurectl\/releases\/download\/1.16.5\/allurectl_linux_386&gt; -O \/usr\/bin\/allurectl<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<pre><code class=\"bash\">- mkdir .allure - mkdir -p \/usr\/bin\/allure-results<\/code><\/pre>\n<p>\u0418 \u0441\u043e\u0437\u0434\u0430\u0435\u043c launch, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<pre><code class=\"bash\">- allurectl launch create --format \"ID\" --no-header &gt; .allure\/launch - export ALLURE_LAUNCH_ID=$(cat .allure\/launch)<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0442\u0435\u0441\u0442\u043e\u0432 \u0432 \u0434\u043e\u043a\u0435\u0440\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c&nbsp; ALLURE_LAUNCH_ID.<\/p>\n<pre><code class=\"bash\">- docker run --name tests -e ENV=stable -e ALLURE_LAUNCH_ID -e $IMAGE_NAME:dev || true true<\/code><\/pre>\n<p>\u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438\u0437 \u0434\u043e\u043a\u0435\u0440\u0430<\/p>\n<pre><code class=\"bash\">- docker cp tests:\/allure-results\/. \/usr\/bin\/allure-results - ls \/usr\/bin\/allure-results<\/code><\/pre>\n<p>\u0412\u044b\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b allurectl<\/p>\n<pre><code class=\"bash\">allurectl upload \/usr\/bin\/allure-results <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0432 \u0433\u0438\u0442\u043b\u0430\u0431\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c variables \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Allure<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/be8\/2aa\/6d5\/be82aa6d510394920190c19590497444.png\" width=\"2020\" height=\"920\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0432\u0441\u0435\u0445 ci-\u0441\u0438\u0441\u0442\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/docs.qameta.io\/allure-testops\/integration\/import-tests-results\/.\">\u0442\u0443\u0442<\/a>. <\/p>\n<p><a href=\"https:\/\/docs.qameta.io\/allure-ee\/import-test-results\/gitlab\/\">\u0414\u043e\u043a\u0430<\/a> \u043f\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u0433\u0438\u0442\u043b\u0430\u0431\u0435. <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 allure \u0432 \u0433\u0438\u0442\u043b\u0430\u0431\u0435 <a href=\"https:\/\/gitlab.com\/eroshenkoam\/allure-example-project\/-\/blob\/gitlab-jobrun\/.gitlab-ci.yml\">gitlab-ci.yml<\/a><\/p>\n<hr>\n<h2>\u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0425\u043e\u0447\u0435\u0442\u0441\u044f \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0437\u044b\u0432 \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a, \u0430 \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0447\u0442\u043e-\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u0434\u043b\u044f \u0432\u0430\u0441 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0438 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043a\u0443\u0447\u043d\u043e, \u0441\u0442\u0430\u0440\u0430\u043b\u0430\u0441\u044c \u0443\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435. \u0418, \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043a \u0432\u0430\u043c \u043f\u0440\u0438\u0448\u043b\u0438 \u043e\u0437\u0430\u0440\u0435\u043d\u0438\u0435 \u0438 \u043d\u043e\u0432\u044b\u0435 \u0438\u0434\u0435\u0438 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0442\u0435\u0441\u0442\u043e\u0432. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u0438\u043b\u0438 \u043e \u0447\u0435\u043c-\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c, \u0442\u043e \u0436\u0434\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432 =)<\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c. \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0422\u0430\u043d\u044f. \u042f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u0443\u044e \u043d\u0430 Go \u0443\u0436\u0435 \u043e\u043a\u043e\u043b\u043e \u0433\u043e\u0434\u0430 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 Vivid Money. \u0414\u043e \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430\u0441\u044c 4 \u0433\u043e\u0434\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 Java.<\/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\/vivid_money\/blog\/566940\/\"> https:\/\/habr.com\/ru\/company\/vivid_money\/blog\/566940\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u043f\u0438\u0441\u0430\u043b\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043d\u0430 Go <\/p>\n<\/li>\n<li>\n<p>\u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c<\/p>\n<\/li>\n<li>\n<p>\u0441 \u043a\u0430\u043a\u0438\u043c\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u044f \u0442\u0435\u0445:<\/p>\n<ul>\n<li>\n<p>\u043a\u0442\u043e \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 Go, \u043a\u0430\u043a \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u044f<\/p>\n<\/li>\n<li>\n<p>\u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 Go \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442, \u0441 \u0447\u0435\u0433\u043e \u043d\u0430\u0447\u0430\u0442\u044c<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u041e \u0447\u0435\u043c \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c<\/strong>:<\/p>\n<ul>\n<li>\n<p><a href=\"#1\">\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 Go \u0438 Allure<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#2\">\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 Allure-go \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#3\">\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 Allure-go<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#4\">Assertion-\u044b \u0432 go, \u0432\u044b\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#5\">O gomega<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#6\">\u041a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c gomega \u0441 allure<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#7\">\u041f\u0440\u043e \u0442\u043e, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0442\u0435\u0441\u0442\u044b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#8\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 REST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#9\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#10\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#11\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 dependency injection<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#12\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0442\u0447\u0435\u0442\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u0438 \u0432 Gitlab-CI<\/a><\/p>\n<\/li>\n<\/ul>\n<details class=\"spoiler\">\n<summary>\u041f\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043c<\/summary>\n<div class=\"spoiler__content\">\n<p>Unit-\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 (\u041c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435) \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<\/p>\n<p>Allure \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0447\u0435\u0442\u044b \u043d\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c \u044f\u0437\u044b\u043a\u0435. \u0412 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u043f\u043e\u0448\u0430\u0433\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441 \u043f\u0440\u0435\u0434\u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432 \u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443. \u0421 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0441\u043d\u043e \u043e\u0442\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0431\u043e\u0441\u0441\u0430\u043c \u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 =)<\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"1\" id=\"1\"><\/a><\/p>\n<h2>\u0412\u044b\u0431\u043e\u0440 \u044f\u0437\u044b\u043a\u0430 Go \u0438 Allure<\/h2>\n<p>\u0412 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445: Java, Kotlin, Scala \u0438 Go. \u0412 \u043c\u043e\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435&nbsp;\u2014 Go.&nbsp; \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e, \u0447\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0442\u043e\u0436\u0435 \u043d\u0430 Go, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043c\u043e\u0447\u044c \u0441 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438&nbsp;\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u2014 \u044d\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043e, \u0433\u0434\u0435 \u043f\u0430\u0434\u0430\u0435\u0442 \u0438 \u043a\u0430\u043a \u043f\u0430\u0434\u0430\u0435\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u044b \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0435 \u043e\u0442\u0447\u0435\u0442\u044b. \u0423 \u043d\u0430\u0441 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 <a href=\"https:\/\/docs.qameta.io\/allure-testops\/\">allure-\u0441\u0435\u0440\u0432\u0435\u0440<\/a>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 Allure.<\/p>\n<p><a class=\"anchor\" name=\"2\" id=\"2\"><\/a><\/p>\n<h2>\u041f\u043e\u0447\u0435\u043c\u0443 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 Allure-go \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/h2>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043e\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u0435\u043b\u0435\u0439 Allure \u0434\u043b\u044f \u044f\u0437\u044b\u043a\u0430 Go, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043d\u0435\u0442 (\u043f\u043e\u043a\u0430 \u043d\u0435\u0442).<\/p>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u044f \u043d\u0430\u0448\u043b\u0430 \u0432\u0441\u0435\u0433\u043e \u0434\u0432\u0435&nbsp;\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 Allure \u0441 Go<\/p>\n<p><a href=\"https:\/\/github.com\/GabbyyLS\/allure-go-common\">Allure-go-common<\/a> \u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 6 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434. \u0418 \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u0430\u0441\u044c, \u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0433\u043e;  \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u0430\u043a\u0430\u044f-\u043b\u0438\u0431\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f.<\/p>\n<p><a href=\"https:\/\/github.com\/dailymotion\/allure-go\">Allure-go<\/a> \u2014 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430, \u0435\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441 \u043c\u043d\u043e\u0433\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u0432\u044b\u0431\u0440\u0430\u043b\u0430 allure-go \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0438 \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0443 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c.<\/p>\n<p><a class=\"anchor\" name=\"3\" id=\"3\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 Allure-go<\/h2>\n<details class=\"spoiler\">\n<summary>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 java<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e, \u043a\u0430\u043a \u044f, \u043f\u0440\u0438\u0448\u0435\u043b \u0438\u0437 Java, \u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e&nbsp;\u043e\u0442\u043b\u0438\u0447\u0438\u044f. <\/p>\n<p>\u041f\u0440\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>Java \u2014 \u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u041a\u043e\u0434 \u043f\u0438\u0448\u0435\u0442\u0441\u044f \u0432 src\/main\/, \u0442\u0435\u0441\u0442\u044b \u043b\u0435\u0436\u0430\u0442 \u0432 src\/test\/<\/p>\n<\/li>\n<li>\n<p>Go \u2014 \u043d\u0435\u0442 \u0447\u0435\u0442\u043a\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438. \u042e\u043d\u0438\u0442 \u0442\u0435\u0441\u0442\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u043b\u0435\u0436\u0430\u0442 \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u0430\u043a\u0435\u0442\u043e\u043c, \u0442.\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0430\u043a\u0435\u0442 sender.go \u0438 \u0440\u044f\u0434\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u043f\u0430\u043f\u043a\u0435 sender_test.go (\u043f\u043e \u043f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u0443 _test \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438)<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0435\u0441\u0442 \u043d\u0430 Java + Allure<\/p>\n<p>\u041d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @Test<\/p>\n<pre><code class=\"java\">@Test func sendTransactionSucc\u0435edTest() {     String clientID = config.GetClientID();     String trxID = apiSteps.SendTransaction(clientID);     Transaction trx = dbSteps.GetTransactionByID(trxID);     assertSteps.CheckTransactionFields(trx); }<\/code><\/pre>\n<p>\u0412 \u0448\u0430\u0433\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @Step<\/p>\n<pre><code class=\"java\">@Step(\u201cSend transaction with clientID \\\\\\\\d+\u201c) func (Steps s) SendTransaction(String clientID) {     String msg = parseJSON();     msg.SetClient(clientID);     s.trxClient.Send(msg); }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 Go \u043d\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439, \u043a\u0430\u043a \u0432 Java. \u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0448\u0430\u0433, \u0442\u0443\u0442 \u043d\u0435 \u043e\u0431\u043e\u0439\u0434\u0435\u0448\u044c\u0441\u044f @step.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0442\u0430\u043a\u0430\u044f \u0436\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 allure.step. \u0412\u043d\u0443\u0442\u0440\u0438 step-a \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 allure.description, \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f allure.Action \u2014 \u0433\u0434\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043c.<\/p>\n<pre><code class=\"go\">func doSomething(){     allure.Step(allure.Description(\"Something\"), allure.Action(func(){         doSomethingNested()     })) }<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0422\u0435\u0441\u0442\u0430 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c allure.Test:<\/p>\n<pre><code class=\"go\">func TestPassedExample(t *testing.T) {     allure.Test(t,                 allure.Description(\"This is a test to show allure implementation with a passing test\"),                 allure.Action(func() {                     s := \"Hello world\"                     if len(s) == 0 {                       \tt.Errorf(\"Expected 'hello world' string, but got %s \", s)                     }                 })) }<\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/dailymotion\/allure-go\/tree\/master\/example\">\u0442\u0443\u0442<\/a>. <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0438\u0448\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u043c\u043e\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p><a class=\"anchor\" name=\"4\" id=\"4\"><\/a><\/p>\n<h2>Assertion-\u044b \u0432 go, \u0432\u044b\u0431\u043e\u0440 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/h2>\n<p>\u0412 \u0442\u0435\u0441\u0442\u0430\u0445 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e assertion-\u044b. <strong>Assertion-\u044b<\/strong> \u2014 \u044d\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0441 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c\u0438. \u0424\u0443\u043d\u043a\u0446\u0438\u0438, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0432 \u043a\u0430\u043a\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443\u043f\u0430\u043b \u0442\u0435\u0441\u0442 \u0438 \u0441 \u043a\u0430\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043a\u043e\u0439.<\/p>\n<p>\u042f \u043d\u0435 \u0441\u0442\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438 \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u0438 \u0441\u0430\u043c \u0442\u0435\u0441\u0442.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435, \u043e\u0434\u043d\u0430 \u0438\u0437 \u0432\u0430\u0436\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 assertion-\u0430 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445, \u044d\u0442\u043e <strong>\u043d\u0435\u044f\u0432\u043d\u044b\u0435 (\u0443\u043c\u043d\u044b\u0435) \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/strong> \u2014 \u043a\u043e\u0433\u0434\u0430&nbsp;\u043e\u0436\u0438\u0434\u0430\u0435\u0448\u044c \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>\u041a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u043f\u043e\u0438\u0441\u043a\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<ol>\n<li>\n<p>\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 Go, Allure <\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u043b\u0438\u0447\u0438\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0423\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c&nbsp;\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0435\u0439 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445, \u0441\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0432\u043e\u0434 \u0432\u0441\u0435\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043f\u043e\u043b\u0435\u0439 (soft assertion)<\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 assertion \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u043e \u044d\u0442\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438<\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>General info<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>C\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c  \u0441 Go, Allure<\/p>\n<\/td>\n<td>\n<p>\u0423\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f<\/p>\n<\/td>\n<td>\n<p>\u0421\u043b\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, soft assertion<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p>Go \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u043a\u0430<\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0435\u0440\u0436\u043a\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438 \u0442\u0435\u0442\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 Go<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/stretchr\/testify\">testify<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438 \u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u043c\u043e\u043a\u043e\u0432.<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/labix.org\/gocheck\">gocheck<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438. \u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 go test. \u0418\u043c\u0435\u0435\u0442 \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441 testify.<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/onsi.github.io\/gomega\/\">gomega<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0441 assertion-\u0430\u043c\u0438. \u0410\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043f\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 BDD \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c Ginkgo. \u041d\u043e \u043c\u043e\u0436\u0435\u0442 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438. <\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/google\/go-cmp\">gocmp<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0411\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u0430\u044f \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0430\u044f \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0430  \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u0438 reflect.DeepEqual<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"113\" width=\"113\">\n<p><a href=\"https:\/\/github.com\/maxatome\/go-testdeep\">go-testdeep<\/a> <\/p>\n<\/td>\n<td data-colwidth=\"178\" width=\"178\">\n<p>\u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0433\u0438\u0431\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u041f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u043d \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u0438\u0437 Test::Deep perl module<\/p>\n<\/td>\n<td data-colwidth=\"94\" width=\"94\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td data-colwidth=\"95\" width=\"95\">\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<td>\n<p>\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p>\u0415\u0441\u0442\u044c<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0418\u0437 \u0432\u0441\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u043d\u043e\u0439 \u0431\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 <a href=\"https:\/\/onsi.github.io\/gomega\/\"><strong>Gomeg\u0430<\/strong><\/a> \u2014 \u0447\u0435\u0442\u043a\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438, \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438, \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 eventually \u0438 consistently, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0443\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435, \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e BDD-\u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f go \u0432\u043c\u0435\u0441\u0442\u043e Allure. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440. <a href=\"https:\/\/onsi.github.io\/ginkgo\/\">Gingko<\/a>, <a href=\"http:\/\/goconvey.co\/\">Goconvey<\/a>, <a href=\"https:\/\/github.com\/franela\/goblin\">Goblin<\/a>. \u0418 \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Allure, \u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0438\u0445 \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c. \u0412\u044b\u0431\u0438\u0440\u0430\u0439\u0442\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0441\u0432\u043e\u0438\u0445 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0442\u0430\u0442\u044c\u0438 \u0441\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/bmuschko.com\/blog\/go-testing-frameworks\/\">https:\/\/bmuschko.com\/blog\/go-testing-frameworks\/<\/a><\/p>\n<p><a href=\"https:\/\/knapsackpro.com\/testing_frameworks\/alternatives_to\/testing\">https:\/\/knapsackpro.com\/testing_frameworks\/alternatives_to\/testing<\/a><\/p>\n<\/div>\n<\/details>\n<p><a class=\"anchor\" name=\"5\" id=\"5\"><\/a><\/p>\n<h2>O gomega<\/h2>\n<p>\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 <a href=\"https:\/\/onsi.github.io\/gomega\/\">Gomega<\/a>?<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 assertion-a<\/p>\n<ul>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <strong>\u03a9<\/strong>:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"go\">\u03a9(ACTUAL).Should(Equal(EXPECTED)) \u03a9(ACTUAL).ShouldNot(Equal(EXPECTED))<\/code><\/pre>\n<ul>\n<li>\n<p>\u0418\u043b\u0438 <strong>Expect<\/strong>:<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"go\">Expect(ACTUAL).To(Equal(EXPECTED)) Expect(ACTUAL).NotTo(Equal(EXPECTED)) Expect(ACTUAL).ToNot(Equal(EXPECTED))<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0442\u0435\u0441\u0442\u0435 \u0441 Allure:<\/p>\n<pre><code class=\"go\">allure.Test(t, allure.Action(func() {     allure.Step(allure.Description(\"Something\"), allure.Action(func() {       gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), \"Text error\")     })) }))<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 <strong>\u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435 \u0430\u0441\u0441\u0435\u0440\u0448\u0435\u043d\u044b<\/strong> (\u0443\u043c\u043d\u044b\u0435 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f) \u0432 Gomega:<\/p>\n<pre><code>Eventually(func() []int {         return thing.SliceImMonitoring }, TIMEOUT, POLLING_INTERVAL).Should(HaveLen(2))<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <strong>eventually<\/strong> \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439 (POLLING_INTERVAL), \u043f\u043e\u043a\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0438\u043b\u0438 \u043d\u0435 \u0438\u0441\u0442\u0435\u0447\u0435\u0442 \u0442\u0430\u0439\u043c\u0430\u0443\u0442.<\/p>\n<p>\u0423\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c&nbsp;\u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0431\u0430\u0437\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. (\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445&#187; \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440)<\/p>\n<p><strong>Consistently<\/strong> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u043c\u0443 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 c \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u043e\u0442\u043e\u0439.<\/p>\n<p>\u0423\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0431\u0430\u0437\u0435 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u0438\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 10 \u0441\u0435\u043a\u0443\u043d\u0434.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"go\">Consistently(func() []int {         return thing.MemoryUsage() }).Should(BeNumerically(\"&lt;\", 10))<\/code><\/pre>\n<p><a class=\"anchor\" name=\"6\" id=\"6\"><\/a><\/p>\n<h2>\u041a\u0430\u043a \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c gomega \u0441 allure<\/h2>\n<p>Gomega \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 BDD \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c Gingko (\u043d\u0430\u043c \u043e\u043d \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u043d\u043e \u0432 \u0434\u043e\u043a\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043d\u0438\u043c, \u0438 \u044d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430 allure \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a).<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u0434\u043b\u044f Gingko \u043d\u0430\u0434\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a, \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0442\u0435\u0441\u0442-\u0441\u044c\u044e\u0442\u0430:<\/p>\n<pre><code class=\"go\">gomega.RegisterFailHandler(ginkgo.Fail)<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 gomega assertion&nbsp;\u0444\u0435\u0439\u043b\u0438\u0442\u0441\u044f, gomega \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>GomegaFailHandler<\/code><strong> <\/strong>(\u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e&nbsp;<code>gomega.RegisterFailHandler()<\/code>)<\/p>\n<p>\u041c\u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0431\u044b\u043b Allure, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0439 FailHandler.<\/p>\n<p><strong>\u041a\u0430\u043a\u0430\u044f \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/strong>. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 gomega \u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0430 gomega c \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>RegisterTestingT<\/code>, \u043a\u0430\u043a \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435<\/p>\n<pre><code class=\"go\">func TestFarmHasCow(t *testing.T) {     gomega.RegisterTestingT(t)      f := farm.New([]string{\"Cow\", \"Horse\"})     gomega.Expect(f.HasCow()).To(BeTrue(), \"Farm should have cow\") }<\/code><\/pre>\n<p><strong>\u0418\u0442\u043e\u0433<\/strong>: \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c, \u0447\u0442\u043e \u0432 Allure \u043e\u0442\u0447\u0435\u0442\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0442 gomega. \u0412\u044b\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u043e\u0442\u0447\u0435\u0442 \u0441 \u0442\u0435\u0441\u0442\u043e\u043c, \u0447\u0442\u043e \u0448\u0430\u0433 \u0437\u0430\u0444\u0435\u0439\u043b\u0438\u043b\u0441\u044f (\u043a\u0430\u043a \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0435), \u043d\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0435 \u0432\u044b\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><strong>\u041a\u0430\u043a \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c<\/strong>. \u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043e\u043a, \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e wrapper, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0444\u0435\u0439\u043b\u0435,&nbsp;\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043c\u0435\u0442\u043e\u0434 <code>allure.Fail<\/code> (\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>allure.error<\/code>, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441 \u0442\u0435\u0441\u0442\u0430 \u2014 fail, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0441\u0442\u0435\u043a\u0442\u0440\u0435\u0439\u0441 \u043e\u0448\u0438\u0431\u043a\u0438)<\/p>\n<pre><code class=\"go\">\/\/\u043d\u0430\u0448 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 wrapper func BuildTestingTGomegaFailWrapper(t *testing.T) *types.GomegaFailWrapper {      \/\/\u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 fail             fail := func(message string, callerSkip ...int) {          \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 allure.fail \u0434\u043b\u044f \u0432\u044b\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043e\u0442\u0447\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438         allure.Fail(errors.New(message))              t.Fatalf(\"\\\\n%s %s\", message, debug.Stack())     }     return &amp;types.GomegaFailWrapper{         Fail:&nbsp; &nbsp;     fail,         TWithHelper: t,     } }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u043c \u0442\u0435\u0441\u0442\u0430, \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f gomega \u0438 \u0432 <code>FailHandler<\/code> \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043d\u0430\u0448 <code>wrapper.BuildTestingTGomegaFailWrapper(t).Fail<\/code><\/p>\n<pre><code class=\"go\">func SetGomegaParameters(t *testing.T) { \t\t\/\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f T \u0432 gomega, \u0447\u0442\u043e\u0431 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c t \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     gomega.RegisterTestingT(t)  \t\t\/\/\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430     gomega.RegisterFailHandler(wrapper.BuildTestingTGomegaFailWrapper(t).Fail) }<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 \u043e\u0442\u0447\u0435\u0442\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430, <\/p>\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-326210","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326210","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=326210"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/326210\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=326210"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=326210"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=326210"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}