{"id":410082,"date":"2024-06-29T21:09:36","date_gmt":"2024-06-29T21:09:36","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=410082"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=410082","title":{"rendered":"<span>\u041a\u0430\u043a \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/96d\/a2f\/a00\/96da2fa004803149266f79eb40554545.jpg\" width=\"1920\" height=\"1080\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/96d\/a2f\/a00\/96da2fa004803149266f79eb40554545.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u0430\u044e\u0442. \u041a\u043e\u0433\u0434\u0430 \u0432 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u0432, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043e\u0441\u0442\u0440\u0430\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u0432\u0435\u0441\u0442\u0438 \u0444\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0447\u0430\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0438\u043b\u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0441\u0447\u0435\u0442 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0434\u0435\u0442 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0438, \u0442\u043e \u043a\u043e\u0434, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u043f\u043b\u043e\u0445\u043e\u043c \u0441\u0442\u0438\u043b\u0435, \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Wrike \u043c\u044b \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0432\u0443\u0445 \u043b\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0432\u044f\u0437\u043a\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 PMD \u0438 Checkstyle. \u0418 \u043e\u043d\u0430 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p><em>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Java \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 JUnit. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Git, \u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 Maven.<\/em><\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b QA Automation \u0432 Wrike \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430 \u043e\u0447\u0435\u043d\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430: \u0432 \u043d\u0430\u0448\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 30 \u0442\u044b\u0441\u044f\u0447 \u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u043a\u043e\u043d\u0442\u0440\u0438\u0431\u044c\u044e\u0442\u044f\u0442 \u0432 \u043d\u0435\u0433\u043e \u0431\u043e\u043b\u0435\u0435 70 \u0447\u0435\u043b\u043e\u0432\u0435\u043a.<\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0438\u043b\u0438 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 private-\u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u0442\u0438\u043b\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0430: \u043f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u0438 \u0442.\u043f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u043e\u0439 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 Epic\/Feature\/Story \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0435\u0433\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 ID \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u0445 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0440\u0435\u0432\u044c\u044e \u043a\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u0434 \u043c\u0435\u0440\u0436\u0435\u043c \u0432\u0435\u0442\u043a\u0438 \u0432 \u043c\u0430\u0441\u0442\u0435\u0440. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u0440\u0435\u0432\u044c\u044e\u0435\u0440 \u2014 \u044d\u0442\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u043c\u043e\u0436\u0435\u0442 \u043e\u0448\u0438\u0431\u0438\u0442\u044c\u0441\u044f. \u0425\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u0440\u0435\u0432\u044c\u044e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b \u043a\u043e\u0434 \u0431\u0435\u0437 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432.<\/p>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 IDE \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u043d\u0441\u043f\u0435\u043a\u0446\u0438\u0439 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u0435\u0437 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438\u043d\u0441\u043f\u0435\u043a\u0446\u0438\u0439 \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 Intellij IDEA \u0443\u0434\u043e\u0431\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u044f\u0436\u0435\u043b\u043e\u0432\u0435\u0441\u043d\u044b\u0439 \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 CI, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u043d\u0430\u0441 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0435\u043b. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 Intellij IDEA.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0441\u0442\u0438\u043b\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430\u043c \u0432 Wrike \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 <a href=\"https:\/\/checkstyle.sourceforge.io\/\"><u>Checkstyle<\/u><\/a>. \u041d\u043e \u043e\u043d \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u0435\u0439\u0441\u044b \u2014 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0442\u0435\u0441\u0442\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0442.\u0434. <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/pmd.github.io\/\"><u>\u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 PMD<\/u><\/a>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u043a\u0435\u0439\u0441\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430. \u041d\u043e \u0443 \u043d\u0435\u0433\u043e \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u2014 PMD \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0444\u0430\u0439\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u042d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043d\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 public-\u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u0430\u043a \u0432 IDE.<\/p>\n<h2>\u041a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c PMD \u0438 Checkstyle<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PMD. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c PMD Java API. \u0425\u043e\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b. \u0422\u043e\u043d\u043a\u043e\u0441\u0442\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 PMD \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/pmd.github.io\/pmd-6.36.0\/pmd_userdocs_tools_java_api.html\"><u>\u0432 \u043c\u0430\u043d\u0443\u0430\u043b\u0435<\/u><\/a>.<\/p>\n<p>PMD \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0442\u0447\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 Report. \u041e\u0442\u0447\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u043c \u0432\u0438\u0434\u0435.<\/p>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 XML-\u0444\u0430\u0439\u043b\u0435, \u0442\u0443\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?>  &lt;ruleset name=\"Custom Ruleset of standard checks\"         xmlns=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0\"         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:schemaLocation=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0 http:\/\/pmd.sourceforge.net\/ruleset_2_0_0.xsd\">     &lt;description>        Ruleset of standard checks.    &lt;\/description>     &lt;exclude-pattern>.*\/com\/wrike\/codestyle\/.*&lt;\/exclude-pattern>     &lt;rule ref=\"category\/java\/codestyle.xml\">        &lt;exclude name=\"LocalVariableCouldBeFinal\"\/> ...    &lt;\/rule> ...    &lt;rule ref=\"category\/java\/codestyle.xml\/FieldNamingConventions\">        &lt;properties>            &lt;property name=\"enumConstantPattern\" value=\"[A-Z][a-zA-Z_0-9]*\"\/>        &lt;\/properties>    &lt;\/rule>  &lt;\/ruleset><\/code><\/pre>\n<p>Checkstyle, \u043a\u0430\u043a \u0438 PMD, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Maven:<\/p>\n<pre><code class=\"xml\">&lt;dependency>    &lt;groupId>com.puppycrawl.tools&lt;\/groupId>    &lt;artifactId>checkstyle&lt;\/artifactId>    &lt;version>8.41&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 Main \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0434\u043b\u044f \u043e\u0442\u0447\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0435\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0415\u0441\u043b\u0438 Checkstyle \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438, \u043e\u043d \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441 \u043a\u043e\u0434\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0438 1. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0435\u0442\u0430. \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e, \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c Checkstyle \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c SecurityManager \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0443, \u0430 \u00ab\u0431\u0440\u043e\u0441\u0430\u043b\u0430\u00bb \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u00ab\u0431\u0440\u043e\u0448\u0435\u043d\u043e\u00bb, \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c.<\/p>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">private void checkCodeStyle(Set&lt;File> fileSet) {    System.setSecurityManager(new SecurityManager() {        @Override        public void checkPermission(Permission perm) {            \/* Allow everything.*\/        }         @Override        public void checkExit(int status) {            \/* Don't allow exit with failed status code.*\/            if (status > 0) {                throw new CodeStyleViolationException();            }        }    });     try {        checkFilesWithCheckStyle(fileSet);    } catch (CodeStyleViolationException e) {        printViolation();    } } <\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u0438\u043b \u0432 Checkstyle \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 XML-\u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;!DOCTYPE module PUBLIC        \"-\/\/Checkstyle\/\/DTD Checkstyle Configuration 1.3\/\/EN\"        \"https:\/\/checkstyle.org\/dtds\/configuration_1_3.dtd\">  &lt;module name=\"Checker\">    &lt;property name=\"charset\" value=\"UTF-8\"\/>     &lt;property name=\"severity\" value=\"error\"\/>     &lt;module name=\"SuppressWarningsFilter\"\/> ...        &lt;module name=\"MethodName\">            &lt;property name=\"format\" value=\"^[a-z][a-zA-Z0-9_]*$\"\/>            &lt;message key=\"name.invalidPattern\"                     value=\"Method name ''{0}'' must match pattern ''{1}''.\"\/>        &lt;\/module> ...        &lt;module name=\"SuppressWarningsHolder\"\/>  &lt;\/module><\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c XML-\u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;!DOCTYPE suppressions PUBLIC        \"-\/\/Checkstyle\/\/DTD SuppressionFilter Configuration 1.2\/\/EN\"        \"https:\/\/checkstyle.org\/dtds\/suppressions_1_2.dtd\">  &lt;suppressions>    &lt;suppress files=\"[\/\\\\]\\.idea[\/\\\\].*\" checks=\".*\"\/>    &lt;suppress files=\"src[\/\\\\]main[\/\\\\]resources[\/\\\\]checkstyle[\/\\\\]\" checks=\".*\"\/> &lt;\/suppressions><\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0431\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c. \u041d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 Checkstyle \u0438 PMD \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>git diff --name-only origin\/master<\/code>. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0432 \u044d\u0442\u043e\u0439 \u0432\u0435\u0442\u043a\u0435 (\u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u043c\u0430\u0441\u0442\u0435\u0440\u043e\u043c). \u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>git fetch<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u00ab\u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u00bb \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c PMD \u0438 Checkstyle \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/wrike\/PMDCheckstyleExample\"><u>\u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c<\/u><\/a>. \u0412 \u043d\u0435\u043c \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432\u0441\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<pre><code class=\"java\">public class CommonTest {     @Test    public void test() {        if (true) {            ;        }    }   } <\/code><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a Checkstyle \u0438 PMD \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">2021-07-20 15:24:41,815 [main] ERROR com.wrike.codestyle.PMDTest -    Problems with PMD, found [2] violation(s)  2021-07-20 15:24:41,815 [main] ERROR com.wrike.codestyle.PMDTest - [ \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java .(CommonTest.java:9)  at line `9` and column `13` Do not use if statements that are always true or always false UnconditionalIfStatement[  public class Foo {     public void close() {         if (true) {        \/\/ fixed conditional, not recommended             \/\/ ...         }     } }          ] check in https:\/\/pmd.github.io\/pmd-6.33.0\/pmd_rules_java_errorprone.html#unconditionalifstatement -----------------------------------------------------------------------------  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java .(CommonTest.java:10)  at line `10` and column `13` An empty statement (semicolon) not part of a loop EmptyStatementNotInLoop[  public void doit() {       \/\/ this is probably not what you meant to do       ;       \/\/ the extra semicolon here this is not necessary       System.out.println(\"look at the extra semicolon\");; }          ]` check in https:\/\/pmd.github.io\/pmd-6.33.0\/pmd_rules_java_errorprone.html#emptystatementnotinloop ----------------------------------------------------------------------------- ]  com.wrike.codestyle.PMDTest$PMDViolationException ...  2021-07-20 15:24:41,829 [main] INFO  com.wrike.codestyle.CheckCodeStyleUtils -  List of 1 files for checking is:  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java  Checkstyle ends with 1 errors. 2021-07-20 15:24:42,416 [main] ERROR com.wrike.codestyle.CheckStyleTest - [  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java:7:5 .(CommonTest.java:7) 'METHOD_DEF' has more than 1 empty lines after. [EmptyLineSeparator] ----------------------------------------] 2021-07-20 15:24:42,417 [main] INFO  com.wrike.codestyle.CheckStyleTest - 2021-07-20 15:24:42,417 [main] INFO  com.wrike.codestyle.CheckStyleTest -  com.wrike.codestyle.CheckStyleTest$CodeStyleViolationException: Your code have [1] violation(s)! Please fix issue. Check logs for more information... <\/code><\/pre>\n<\/div>\n<\/details>\n<h2>\u041a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/h2>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b PMD \u0438 Checkstyle \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0435 \u0432\u0441\u0435 \u043a\u0435\u0439\u0441\u044b. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f PMD \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438\u0445 \u043a \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c. \u0414\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043c\u044b \u0441\u043e\u0432\u0435\u0442\u0443\u0435\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 <a href=\"https:\/\/pmd.github.io\/pmd-6.36.0\/pmd_userdocs_extending_writing_rules_intro.html\"><u>\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 PMD<\/u><\/a> \u043f\u043e AST-\u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c.<\/p>\n<p><strong>\u0423\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432.<\/strong>  \u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0433\u043e\u043d\u043e\u0432 \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/youtu.be\/O6X2-1uoqAw\"><u>Allure Server<\/u><\/a>. \u0427\u0442\u043e\u0431\u044b \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0442\u0435\u0441\u0442\u0430 \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u043c, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@TestCaseId<\/code>. Allure Server \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0442\u0435\u0441\u0442\u0430, \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u043d\u0430 \u0435\u0433\u043e ID. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043c\u044f \u0442\u0435\u0441\u0442\u0430, \u043d\u043e \u043e\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f, \u0430 ID \u2014 \u043d\u0435\u0442.<\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u0441\u0442\u0430 \u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0443 \u043d\u0435\u0433\u043e ID \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u0432\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b\u0430: <code>CheckDuplicateTestIdRule<\/code> \u0438 <code>TestMustHaveTestIdAnnotationRule<\/code>.\u00a0<\/p>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e TestMustHaveTestIdAnnotationRule \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 ID \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430. \u0415\u0441\u043b\u0438 \u0443 \u043c\u0435\u0442\u043e\u0434\u0430 \u0435\u0441\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@Test<\/code> \u0438\u043b\u0438 <code>@ParameterizedTest<\/code> \u0438\u0437 JUnit5, \u0442\u043e \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e <code>@TestCaseId<\/code>:<\/p>\n<pre><code class=\"java\">public class TestMustHaveTestIdAnnotationRule extends AbstractJavaRule {     @Override    public Object visit(final ASTMethodDeclaration node, final Object data) {        ASTAnnotation testAnnotation = node.getAnnotation(Test.class.getCanonicalName());        ASTAnnotation parameterizedTestAnnotation = node.getAnnotation(ParameterizedTest.class.getCanonicalName());         if (testAnnotation != null || parameterizedTestAnnotation != null) {            ASTAnnotation testCaseIdAnnotation = node.getAnnotation(TestCaseId.class.getCanonicalName());            if (testCaseIdAnnotation == null) {                addViolation(data, node);            }        }        return super.visit(node, data);    } }<\/code><\/pre>\n<p>\u041f\u0440\u0430\u0432\u0438\u043b\u043e <code>CheckDuplicateTestIdRule<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e ID \u0432\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0435 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0442\u0441\u044f. \u041a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043e\u0442\u0447\u0435\u0442\u0435 \u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438, \u0432 \u043a\u0430\u043a\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043e\u0448\u0438\u0431\u043a\u0430. \u041c\u0435\u0442\u043e\u0434 <code>findAllIds<\/code> \u0438\u0449\u0435\u0442 \u0432\u0441\u0435 ID \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0434\u043b\u044f \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<pre><code class=\"java\">public class CheckDuplicateTestIdRule extends AbstractJavaRule {     @Override    public Object visit(final ASTMethodDeclaration node, final Object data) {        ASTAnnotation testCaseIdAnnotation = node.getAnnotation(TestCaseId.class.getCanonicalName());        if (testCaseIdAnnotation != null) {            Map&lt;Integer, Integer> allIds = DuplicateTestCaseIdUtils.findAllIds();            ASTSingleMemberAnnotation memberAnnotation = (ASTSingleMemberAnnotation) testCaseIdAnnotation.getChild(0);            memberAnnotation.findDescendantsOfType(ASTLiteral.class).stream()                    .map(ASTLiteral::getValueAsInt)                    .filter(it -> allIds.get(it) > 1)                    .forEach(it -> addViolation(data, node, it.toString()));        }         return super.visit(node, data);    } }<\/code><\/pre>\n<p>\u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u0441 ID \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 ID \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 <code>ParametrizedTestIdsCountRule<\/code>. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e ID \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0432\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0442\u0435\u0441\u0442\u044b \u043d\u0435 \u00ab\u0442\u0435\u0440\u044f\u043b\u0438\u0441\u044c\u00bb \u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0438 \u0432 \u043e\u0442\u0447\u0435\u0442\u044b Allure. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u0435\u0442\u043e\u0434 provider \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043a\u043b\u0430\u0441\u0441\u0435, \u0447\u0442\u043e \u0438 \u0442\u0435\u0441\u0442\u044b \u2014 \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 PMD, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043e\u0431\u043e\u0439\u0442\u0438.\u00a0<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@EnumSource<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e Enum \u043c\u043e\u0436\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0444\u0430\u0439\u043b\u0435. \u0412\u043c\u0435\u0441\u0442\u043e <code>@EnumSource<\/code> \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>@MethodSource<\/code>. \u041c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430, \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 ID. \u0412 \u0441\u043b\u0443\u0447\u0430\u044f\u0445, \u043a\u043e\u0433\u0434\u0430 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0430\u0432\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@SuppressWarnings<\/code>. \u041a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 <code>ParametrizedTestIdsCountRule<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/wrike\/PMDCheckstyleExample\"><u>\u0432 \u0433\u043e\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/u><\/a>.\u00a0<\/p>\n<p>\u0412\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b, \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438\u0445 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 <code>pmd-testcaseid-ruleset.xml<\/code> \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0433\u043e:<\/p>\n<details class=\"spoiler\">\n<summary>pmd-testcaseid-ruleset.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?>  &lt;ruleset name=\"TestCaseId rule set\"         xmlns=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0\"         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:schemaLocation=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0 http:\/\/pmd.sourceforge.net\/ruleset_2_0_0.xsd\">     &lt;description>        Rules for check tests ids    &lt;\/description>     &lt;rule name=\"TestMustHaveTestIdAnnotationRule\"          language=\"java\"          class=\"com.wrike.checkstyle.wrikerules.TestMustHaveTestIdAnnotationRule\"          message=\"You have to use @TestCaseId with @Test annotation.\">        &lt;description>            You have to use @TestCaseId with @Test annotation.        &lt;\/description>        &lt;priority>1&lt;\/priority>    &lt;\/rule>     &lt;rule name=\"CheckDuplicateTestIdRule\"          language=\"java\"          class=\"com.wrike.checkstyle.wrikerules.CheckDuplicateTestIdRule\"          message=\"There is a duplicate @TestCaseId {0}\">        &lt;description>            There is a duplicate @TestCaseId.        &lt;\/description>        &lt;priority>1&lt;\/priority>    &lt;\/rule>     &lt;rule name=\"ParametrizedTestIdsCountRule\"          language=\"java\"          class=\"com.wrike.checkstyle.wrikerules.ParametrizedTestIdsCountRule\"          message=\"Unexpected test case ids count for parametrized test. Expected {0} ids, but found {1} ids.\">        &lt;description>            Check that parameterized tests have the right count of test case ids.        &lt;\/description>        &lt;priority>1&lt;\/priority>    &lt;\/rule>  &lt;\/ruleset> <\/code><\/pre>\n<\/div>\n<\/details>\n<p><strong>\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0442\u0435\u0441\u0442\u043e\u0432.<\/strong>  \u0418\u043d\u043e\u0433\u0434\u0430 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443 \u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u0440\u0438\u0437\u043d\u0430\u043a\u0443. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 JUnit5 \u0435\u0441\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f Tag. \u0412 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Wrike \u043c\u044b \u0440\u0430\u0437\u043c\u0435\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u0435\u0433\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0442\u0435\u0441\u0442\u043e\u0432. \u0422\u0435\u0441\u0442 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>ScreenshotSteps<\/code>.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0435\u0441\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u043e \u043d\u0435\u043c\u0443 \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434 \u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0430 <code>ScreenshotSteps<\/code>, \u0442\u043e \u0442\u0435\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u0435\u0433\u043e\u043c.<\/p>\n<p>\u0421\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 ScreenshotTestMustHaveScreenshotTag <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">public class ScreenshotTestMustHaveScreenshotTag extends AbstractJavaRule {     private static final String SCREENSHOT_TAG = \"SCREENSHOT_TEST\";     private Map&lt;ASTMethodDeclaration, Set&lt;ASTMethodDeclaration>> screenshotMethodUsages;    private Map&lt;ASTMethodDeclaration, Set&lt;ASTMethodDeclaration>> methodUsages;    private final Set&lt;ASTMethodDeclaration> visitedMethods = new HashSet&lt;>();     @Override    public Object visit(final ASTClassOrInterfaceDeclaration node, final Object data) {         if (nodeHasScreenshotTag(node)) {            return super.visit(node, data);        }         Optional&lt;Entry&lt;VariableNameDeclaration, List&lt;NameOccurrence>>> screenshotStepsDeclaration = getScreenshotStepsDeclaration(node);        if (screenshotStepsDeclaration.isEmpty()) {            return super.visit(node, data);        }         Set&lt;ASTMethodDeclaration> screenshotMethods = getScreenshotMethods(screenshotStepsDeclaration);         methodUsages = getMethodUsages(node);         screenshotMethodUsages = methodUsages.entrySet().stream()                .filter(entry -> screenshotMethods.contains(entry.getKey()))                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));         Set&lt;ASTMethodDeclaration> allScreenshotMethods = dfsTree();         allScreenshotMethods.forEach(method -> {            Set&lt;? extends Class&lt;?>> annotationSet = getAnnotations(method);            if ((annotationSet.contains(ParameterizedTest.class) || annotationSet.contains(Test.class))                    &amp;&amp; !nodeHasScreenshotTag(method)) {                addViolation(data, method);            }        });         return super.visit(node, data);    }  }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/youtu.be\/Y4I6Vp4sk_o\"><u>Epic\/Feature\/Story<\/u><\/a> \u2014 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 Allure. \u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u044f\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438: \u0442\u0435\u0441\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d <code>@Epic<\/code> \u0438 \u043d\u0435 \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0439 <code>@Feature<\/code> \u0438 <code>@Story<\/code>.\u00a0<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 TestShouldHaveOneEntity<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"java\">public abstract class TestShouldHaveOneEntity extends AbstractJavaRule {     private static final String TEST_METHOD_JUNIT4_OR_JUNIT5 = \"Test\";    private final String entityAnnotation;    private final String multipleEntityAnnotation;    private final boolean mustHaveAnnotation;     public TestShouldHaveOneEntity(String annotationEntity, String multipleEntityAnnotation, boolean mustHaveAnnotation) {        super();        this.entityAnnotation = annotationEntity;        this.multipleEntityAnnotation = multipleEntityAnnotation;        this.mustHaveAnnotation = mustHaveAnnotation;    }     @Override    public Object visit(final ASTMethodDeclaration node, final Object data) {        Set&lt;String> annotationNameSet = getMethodAnnotations(node);        if (annotationNameSet.contains(TEST_METHOD_JUNIT4_OR_JUNIT5)) {            Set&lt;String> classAnnotationNameSet = getClassAnnotations(node);            if (annotationNameSet.stream().anyMatch(annotation -> annotation.equals(multipleEntityAnnotation))                    || classAnnotationNameSet.stream().anyMatch(annotation -> annotation.equals(multipleEntityAnnotation))) {                addViolation(data, node);                return super.visit(node, data);             }            boolean methodHasEntityAnnotation = annotationNameSet.stream().anyMatch(annotation -> annotation.equals(entityAnnotation));            boolean classHasEntityAnnotation = classAnnotationNameSet.stream().anyMatch(annotation -> annotation.equals(entityAnnotation));            if (mustHaveAnnotation &amp;&amp; methodHasEntityAnnotation == classHasEntityAnnotation) {                addViolation(data, node);                return super.visit(node, data);            }            if (!mustHaveAnnotation &amp;&amp; methodHasEntityAnnotation &amp;&amp; classHasEntityAnnotation) {                addViolation(data, node);            }        }        return super.visit(node, data);    }  }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f <code>@Epic<\/code>, <code>@Feature<\/code> \u0438 <code>@Story<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"java\">public class TestShouldHaveOnlyOneEpic extends TestShouldHaveOneEntity {     public TestShouldHaveOnlyOneEpic() {        super(Epic.class.getSimpleName(), Epics.class.getSimpleName(), true);    }  }  public class TestShouldHaveNoMoreThanOneStory extends TestShouldHaveOneEntity {     public TestShouldHaveNoMoreThanOneStory() {        super(Story.class.getSimpleName(), Stories.class.getSimpleName(), false);    }  }  public class TestShouldHaveNoMoreThanOneFeature extends TestShouldHaveOneEntity {     public TestShouldHaveNoMoreThanOneFeature() {        super(Feature.class.getSimpleName(), Features.class.getSimpleName(), false);    }  }<\/code><\/pre>\n<p><strong>\u0414\u0440\u0443\u0433\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/strong>  \u0415\u0449\u0435 \u043e\u0434\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 <code>@RepeatedTest<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>@Test<\/code>. \u041e\u0431\u044b\u0447\u043d\u043e \u0442\u0430\u043a\u0430\u044f \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0442\u0435\u0441\u0442\u044b \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041d\u0430 \u0440\u0435\u0432\u044c\u044e \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u0443\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u0438 \u0442\u0435\u0441\u0442 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0434\u043d\u043e\u0433\u043e. \u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0438\u043c\u043f\u043e\u0440\u0442 <code>@RepeatedTest<\/code> \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u043c. \u0415\u0441\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0437\u0430\u043f\u0443\u0448\u0438\u043b \u0432\u0435\u0442\u043a\u0443 \u0441 \u044d\u0442\u043e\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439, \u043e\u0448\u0438\u0431\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043b\u043e\u0432\u043b\u0435\u043d\u0430 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u0430 \u0432 CI.<\/p>\n<pre><code class=\"java\">public class ShouldNotImportRepeatedTest extends AbstractJavaRule {     private static final String REPEATED_TEST = RepeatedTest.class.getCanonicalName();     @Override    public Object visit(final ASTImportDeclaration node, final Object data) {        String nodeImportedName = node.getImportedName();        if (nodeImportedName.contains(REPEATED_TEST)) {            addViolation(data, node);            return super.visit(node, data);        }         return super.visit(node, data);    }  }<\/code><\/pre>\n<p>\u0412 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Wrike \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c 62 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 Checkstyle \u0438 271 \u043f\u0440\u0430\u0432\u0438\u043b\u043e PMD, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 236 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0438 35 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445. \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0438\u0437 38\u043a \u0442\u0435\u0441\u0442\u043e\u0432 \u0438 13\u043a Java \u0444\u0430\u0439\u043b\u043e\u0432, \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 10 \u043c\u0438\u043d\u0443\u0442. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 diff \u043c\u0435\u0436\u0434\u0443 \u0432\u0435\u0442\u043a\u043e\u0439 \u0438 \u043c\u0430\u0441\u0442\u0435\u0440\u043e\u043c \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0435 100 \u0444\u0430\u0439\u043b\u043e\u0432, \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 2-3 \u043c\u0438\u043d\u0443\u0442\u044b.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044e Checkstyle \u0438 PMD \u043d\u0430\u043c \u0443\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u0442\u043e\u0442\u0443 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0438 \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u043a\u0443 PMD \u0438 Checkstyle, \u0438\u0449\u0438\u0442\u0435 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 <a href=\"https:\/\/github.com\/wrike\/PMDCheckstyleExample\"><u>\u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435<\/u><\/a>.<\/p>\n<p>\u0410 \u043a\u0430\u043a\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0432 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u0432\u044b?<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/574320\/\"> https:\/\/habr.com\/ru\/articles\/574320\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0433\u0430\u044e\u0442. \u041a\u043e\u0433\u0434\u0430 \u0432 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043e\u0432, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u043e\u0441\u0442\u0440\u0430\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u0432\u0435\u0441\u0442\u0438 \u0444\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435 \u0447\u0430\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u044b \u043f\u0438\u0448\u0443\u0442\u0441\u044f \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0438\u043b\u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438. \u041a\u043e\u0433\u0434\u0430 \u0441\u0447\u0435\u0442 \u0442\u0435\u0441\u0442\u043e\u0432 \u0438\u0434\u0435\u0442 \u043d\u0430 \u0442\u044b\u0441\u044f\u0447\u0438, \u0442\u043e \u043a\u043e\u0434, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u043f\u043b\u043e\u0445\u043e\u043c \u0441\u0442\u0438\u043b\u0435, \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 Wrike \u043c\u044b \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0432\u0443\u0445 \u043b\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u0432\u044f\u0437\u043a\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 PMD \u0438 Checkstyle. \u0418 \u043e\u043d\u0430 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p><em>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u0434\u0430 \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Java \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 JUnit. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u0435\u0440\u0441\u0438\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Git, \u0430 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u2014 Maven.<\/em><\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b QA Automation \u0432 Wrike \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430 \u043e\u0447\u0435\u043d\u044c \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u0430: \u0432 \u043d\u0430\u0448\u0435\u043c \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 30 \u0442\u044b\u0441\u044f\u0447 \u0442\u0435\u0441\u0442\u043e\u0432, \u0430 \u043a\u043e\u043d\u0442\u0440\u0438\u0431\u044c\u044e\u0442\u044f\u0442 \u0432 \u043d\u0435\u0433\u043e \u0431\u043e\u043b\u0435\u0435 70 \u0447\u0435\u043b\u043e\u0432\u0435\u043a.<\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0447\u0430\u0441\u0442\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u044b \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0435\u043c\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u041d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0438\u043b\u0438 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 private-\u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043b\u0438\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0435 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044f\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u0442\u0438\u043b\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0430: \u043f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u0438 \u0442.\u043f.<\/p>\n<\/li>\n<\/ul>\n<p>\u0410 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u043e\u0439 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p>\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0430 Epic\/Feature\/Story \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0435\u0433\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u0442\u0435\u0441\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 ID \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u043a\u043e\u0434\u0430 \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f\u0445 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u0440\u0435\u0432\u044c\u044e \u043a\u043e\u0434\u0430 \u043f\u0435\u0440\u0435\u0434 \u043c\u0435\u0440\u0436\u0435\u043c \u0432\u0435\u0442\u043a\u0438 \u0432 \u043c\u0430\u0441\u0442\u0435\u0440. \u0422\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u043e, \u043d\u043e \u0440\u0435\u0432\u044c\u044e\u0435\u0440 \u2014 \u044d\u0442\u043e \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a \u043c\u043e\u0436\u0435\u0442 \u043e\u0448\u0438\u0431\u0438\u0442\u044c\u0441\u044f. \u0425\u043e\u0447\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u0440\u0435\u0432\u044c\u044e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b \u043a\u043e\u0434 \u0431\u0435\u0437 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432.<\/p>\n<p>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 IDE \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u0438\u043d\u0441\u043f\u0435\u043a\u0446\u0438\u0439 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0431\u0435\u0437 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438\u043d\u0441\u043f\u0435\u043a\u0446\u0438\u0439 \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0439 Intellij IDEA \u0443\u0434\u043e\u0431\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u044f\u0436\u0435\u043b\u043e\u0432\u0435\u0441\u043d\u044b\u0439 \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432 CI, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u043d\u0430\u0441 \u043d\u0435 \u043f\u043e\u0434\u043e\u0448\u0435\u043b. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 Intellij IDEA.<\/p>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0441\u0435 \u0441\u0442\u0438\u043b\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430\u043c \u0432 Wrike \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 <a href=\"https:\/\/checkstyle.sourceforge.io\/\"><u>Checkstyle<\/u><\/a>. \u041d\u043e \u043e\u043d \u043d\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u0435\u0439\u0441\u044b \u2014 \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0442\u0435\u0441\u0442\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 \u043a\u043e\u0434\u0435 \u0438 \u0442.\u0434. <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/pmd.github.io\/\"><u>\u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 PMD<\/u><\/a>. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u043a\u0435\u0439\u0441\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0438 \u0444\u0430\u0439\u043b\u0430. \u041d\u043e \u0443 \u043d\u0435\u0433\u043e \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u2014 PMD \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0444\u0430\u0439\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432. \u042d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043d\u043e \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 public-\u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u0430\u043a \u0432 IDE.<\/p>\n<h2>\u041a\u0430\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c PMD \u0438 Checkstyle<\/h2>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 PMD. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c PMD Java API. \u0425\u043e\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u043d\u0435 \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0433\u0438\u0431\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b. \u0422\u043e\u043d\u043a\u043e\u0441\u0442\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 PMD \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/pmd.github.io\/pmd-6.36.0\/pmd_userdocs_tools_java_api.html\"><u>\u0432 \u043c\u0430\u043d\u0443\u0430\u043b\u0435<\/u><\/a>.<\/p>\n<p>PMD \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0442\u0447\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043b\u0430\u0441\u0441\u0430 Report. \u041e\u0442\u0447\u0435\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u043c \u0432\u0438\u0434\u0435.<\/p>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 XML-\u0444\u0430\u0439\u043b\u0435, \u0442\u0443\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?>  &lt;ruleset name=\"Custom Ruleset of standard checks\"         xmlns=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0\"         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"         xsi:schemaLocation=\"http:\/\/pmd.sourceforge.net\/ruleset\/2.0.0 http:\/\/pmd.sourceforge.net\/ruleset_2_0_0.xsd\">     &lt;description>        Ruleset of standard checks.    &lt;\/description>     &lt;exclude-pattern>.*\/com\/wrike\/codestyle\/.*&lt;\/exclude-pattern>     &lt;rule ref=\"category\/java\/codestyle.xml\">        &lt;exclude name=\"LocalVariableCouldBeFinal\"\/> ...    &lt;\/rule> ...    &lt;rule ref=\"category\/java\/codestyle.xml\/FieldNamingConventions\">        &lt;properties>            &lt;property name=\"enumConstantPattern\" value=\"[A-Z][a-zA-Z_0-9]*\"\/>        &lt;\/properties>    &lt;\/rule>  &lt;\/ruleset><\/code><\/pre>\n<p>Checkstyle, \u043a\u0430\u043a \u0438 PMD, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Maven:<\/p>\n<pre><code class=\"xml\">&lt;dependency>    &lt;groupId>com.puppycrawl.tools&lt;\/groupId>    &lt;artifactId>checkstyle&lt;\/artifactId>    &lt;version>8.41&lt;\/version> &lt;\/dependency><\/code><\/pre>\n<p>\u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 Main \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u0434\u043b\u044f \u043e\u0442\u0447\u0435\u0442\u0430. \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0435\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0415\u0441\u043b\u0438 Checkstyle \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0438, \u043e\u043d \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0441 \u043a\u043e\u0434\u043e\u043c \u043e\u0448\u0438\u0431\u043a\u0438 1. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b \u043e\u0442\u0447\u0435\u0442\u0430. \u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0433\u043e, \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435\u043c Checkstyle \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c SecurityManager \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u0443, \u0430 \u00ab\u0431\u0440\u043e\u0441\u0430\u043b\u0430\u00bb \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435. \u0415\u0441\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u00ab\u0431\u0440\u043e\u0448\u0435\u043d\u043e\u00bb, \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u043e\u0442\u0447\u0435\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c.<\/p>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"java\">private void checkCodeStyle(Set&lt;File> fileSet) {    System.setSecurityManager(new SecurityManager() {        @Override        public void checkPermission(Permission perm) {            \/* Allow everything.*\/        }         @Override        public void checkExit(int status) {            \/* Don't allow exit with failed status code.*\/            if (status > 0) {                throw new CodeStyleViolationException();            }        }    });     try {        checkFilesWithCheckStyle(fileSet);    } catch (CodeStyleViolationException e) {        printViolation();    } } <\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u0430\u0432\u0438\u043b \u0432 Checkstyle \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 XML-\u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;!DOCTYPE module PUBLIC        \"-\/\/Checkstyle\/\/DTD Checkstyle Configuration 1.3\/\/EN\"        \"https:\/\/checkstyle.org\/dtds\/configuration_1_3.dtd\">  &lt;module name=\"Checker\">    &lt;property name=\"charset\" value=\"UTF-8\"\/>     &lt;property name=\"severity\" value=\"error\"\/>     &lt;module name=\"SuppressWarningsFilter\"\/> ...        &lt;module name=\"MethodName\">            &lt;property name=\"format\" value=\"^[a-z][a-zA-Z0-9_]*$\"\/>            &lt;message key=\"name.invalidPattern\"                     value=\"Method name ''{0}'' must match pattern ''{1}''.\"\/>        &lt;\/module> ...        &lt;module name=\"SuppressWarningsHolder\"\/>  &lt;\/module><\/code><\/pre>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c XML-\u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code class=\"xml\">&lt;?xml version=\"1.0\"?> &lt;!DOCTYPE suppressions PUBLIC        \"-\/\/Checkstyle\/\/DTD SuppressionFilter Configuration 1.2\/\/EN\"        \"https:\/\/checkstyle.org\/dtds\/suppressions_1_2.dtd\">  &lt;suppressions>    &lt;suppress files=\"[\/\\\\]\\.idea[\/\\\\].*\" checks=\".*\"\/>    &lt;suppress files=\"src[\/\\\\]main[\/\\\\]resources[\/\\\\]checkstyle[\/\\\\]\" checks=\".*\"\/> &lt;\/suppressions><\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043e\u0431\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c. \u041d\u0435 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 Checkstyle \u0438 PMD \u043f\u043e \u0432\u0441\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u0435\u0441\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0438\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432. \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>git diff --name-only origin\/master<\/code>. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b \u0432 \u044d\u0442\u043e\u0439 \u0432\u0435\u0442\u043a\u0435 (\u0432 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0438 \u0441 \u043c\u0430\u0441\u0442\u0435\u0440\u043e\u043c). \u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430 <code>git fetch<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u00ab\u043f\u043e\u0434\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442\u00bb \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c PMD \u0438 Checkstyle \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/wrike\/PMDCheckstyleExample\"><u>\u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c<\/u><\/a>. \u0412 \u043d\u0435\u043c \u0443\u0436\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432\u0441\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430:<\/p>\n<pre><code class=\"java\">public class CommonTest {     @Test    public void test() {        if (true) {            ;        }    }   } <\/code><\/pre>\n<p>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a Checkstyle \u0438 PMD \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u0412\u044b\u0432\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">2021-07-20 15:24:41,815 [main] ERROR com.wrike.codestyle.PMDTest -    Problems with PMD, found [2] violation(s)  2021-07-20 15:24:41,815 [main] ERROR com.wrike.codestyle.PMDTest - [ \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java .(CommonTest.java:9)  at line `9` and column `13` Do not use if statements that are always true or always false UnconditionalIfStatement[  public class Foo {     public void close() {         if (true) {        \/\/ fixed conditional, not recommended             \/\/ ...         }     } }          ] check in https:\/\/pmd.github.io\/pmd-6.33.0\/pmd_rules_java_errorprone.html#unconditionalifstatement -----------------------------------------------------------------------------  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java .(CommonTest.java:10)  at line `10` and column `13` An empty statement (semicolon) not part of a loop EmptyStatementNotInLoop[  public void doit() {       \/\/ this is probably not what you meant to do       ;       \/\/ the extra semicolon here this is not necessary       System.out.println(\"look at the extra semicolon\");; }          ]` check in https:\/\/pmd.github.io\/pmd-6.33.0\/pmd_rules_java_errorprone.html#emptystatementnotinloop ----------------------------------------------------------------------------- ]  com.wrike.codestyle.PMDTest$PMDViolationException ...  2021-07-20 15:24:41,829 [main] INFO  com.wrike.codestyle.CheckCodeStyleUtils -  List of 1 files for checking is:  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java  Checkstyle ends with 1 errors. 2021-07-20 15:24:42,416 [main] ERROR com.wrike.codestyle.CheckStyleTest - [  \/src\/test\/java\/com\/wrike\/tests\/CommonTest.java:7:5 .(CommonTest.java:7) 'METHOD_DEF' has more than 1 empty lines after. [EmptyLineSeparator] ----------------------------------------] 2021-07-20 15:24:42,417 [main] INFO  com.wrike.codestyle.CheckStyleTest - 2021-07-20 15:24:42,417 [main] INFO  com.wrike.codestyle.CheckStyleTest -  com.wrike.codestyle.CheckStyleTest$CodeStyleViolationException: Your code have [1] violation(s)! Please fix issue. Check logs for more information... <\/code><\/pre>\n<\/div>\n<\/details>\n<h2>\u041a\u0430\u043a \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/h2>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b PMD \u0438 Checkstyle \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0435 \u0432\u0441\u0435 \u043a\u0435\u0439\u0441\u044b. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f PMD \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0438\u0445 \u043a \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u043c. \u0414\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u043c\u044b \u0441\u043e\u0432\u0435\u0442\u0443\u0435\u043c \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 <a href=\"https:\/\/pmd.github.io\/pmd-6.36.0\/pmd_userdocs_extending_writing_rules_intro.html\"><u>\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 PMD<\/u><\/a> \u043f\u043e<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-410082","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/410082","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=410082"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/410082\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=410082"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=410082"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=410082"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}