{"id":29330,"date":"2026-09-14T23:50:48","date_gmt":"2026-09-14T23:50:48","guid":{"rendered":"https:\/\/umang.pk\/2026\/09\/14\/%d9%85%db%8c%d8%b1%d8%a7%d8%ab%db%8c-%d9%85%d9%86%d8%aa%d9%82%d9%84%db%8c-%da%a9%db%92-%d8%af%d9%88%d8%b1%d8%a7%d9%86-%d8%aa%d9%81%d8%b1%db%8c%d9%82-%d9%b9%db%8c%d8%b3%d9%b9%d9%86%da%af-%da%a9%d8%a7\/"},"modified":"2026-09-14T23:50:48","modified_gmt":"2026-09-14T23:50:48","slug":"%d9%85%db%8c%d8%b1%d8%a7%d8%ab%db%8c-%d9%85%d9%86%d8%aa%d9%82%d9%84%db%8c-%da%a9%db%92-%d8%af%d9%88%d8%b1%d8%a7%d9%86-%d8%aa%d9%81%d8%b1%db%8c%d9%82-%d9%b9%db%8c%d8%b3%d9%b9%d9%86%da%af-%da%a9%d8%a7","status":"publish","type":"post","link":"https:\/\/umang.pk\/en_us\/2026\/09\/14\/%d9%85%db%8c%d8%b1%d8%a7%d8%ab%db%8c-%d9%85%d9%86%d8%aa%d9%82%d9%84%db%8c-%da%a9%db%92-%d8%af%d9%88%d8%b1%d8%a7%d9%86-%d8%aa%d9%81%d8%b1%db%8c%d9%82-%d9%b9%db%8c%d8%b3%d9%b9%d9%86%da%af-%da%a9%d8%a7\/","title":{"rendered":"\u0645\u06cc\u0631\u0627\u062b\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679\u0646\u06af \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc\u0633\u06d2 \u06a9\u0631\u06cc\u06ba\u06d4"},"content":{"rendered":"\n<div id=\"\">\n<p>\u0648\u0631\u0627\u062b\u062a \u06a9\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u0627 \u0633\u0628 \u0633\u06d2 \u062e\u0637\u0631\u0646\u0627\u06a9 \u0644\u0645\u062d\u06c1 \u0636\u0631\u0648\u0631\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u062c\u0628 \u0622\u067e \u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0644\u06a9\u06be\u0646\u0627 \u0634\u0631\u0648\u0639 \u06a9\u0631\u06cc\u06ba\u06d4 \u0646\u06cc\u0627 \u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u0645\u06a9\u0645\u0644 \u06c1\u0648\u062a\u0627 \u062f\u06a9\u06be\u0627\u0626\u06cc \u062f\u06d2 \u0631\u06c1\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u067e \u06a9\u0627 \u06a9\u0648\u0688 \u0645\u0631\u062a\u0628 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u060c \u0622\u067e \u06a9\u06d2 \u0679\u06cc\u0633\u0679 \u067e\u0627\u0633 \u06c1\u0648\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u0622\u067e \u06a9\u0627 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u0635\u0627\u0641 \u0633\u062a\u06be\u0631\u0627 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0622\u067e \u06a9\u06cc \u0646\u0626\u06cc \u0633\u0631\u0648\u0633 \u062a\u06cc\u0632\u06cc \u0633\u06d2 \u062c\u0648\u0627\u0628 \u062f\u06cc\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u067e\u06be\u0631 \u0633\u0628 \u0627\u06cc\u06a9 \u06c1\u06cc \u0633\u0648\u0627\u0644 \u06a9\u0631\u0646\u06d2 \u0644\u06af\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<blockquote>\n<p>\u06a9\u06cc\u0627 \u0622\u067e \u0627\u0628 \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u061f<\/p>\n<\/blockquote>\n<p>\u06cc\u06c1 \u0648\u06c1 \u062c\u06af\u06c1 \u06c1\u06d2 \u062c\u06c1\u0627\u06ba \u0627\u0639\u062a\u0645\u0627\u062f \u0645\u0634\u06a9\u0644 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0627\u067e\u0646\u06d2 \u0679\u06cc\u0633\u0679 \u0633\u0648\u0679 \u06a9\u0648 \u067e\u0627\u0633 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u067e\u06be\u0631 \u0628\u06be\u06cc \u0627\u0633 \u0646\u0638\u0627\u0645 \u0633\u06d2 \u0645\u062e\u062a\u0644\u0641 \u0628\u0631\u062a\u0627\u0624 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u062c\u0633\u06d2 \u0648\u06c1 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u0631\u0627\u0624\u0646\u0688\u0646\u06af \u062a\u0628\u062f\u06cc\u0644 \u06c1\u0648 \u06af\u0626\u06cc \u06c1\u0648\u060c \u06a9\u0627\u0644\u0639\u062f\u0645 \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u0645\u062e\u062a\u0644\u0641 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u06c1\u06cc\u0646\u0688\u0644 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u060c \u06cc\u0627 \u06a9\u0633\u06cc \u063a\u0644\u0637\u06cc \u06a9\u06d2 \u0646\u062a\u06cc\u062c\u06d2 \u0645\u06cc\u06ba \u06a9\u0627\u0645\u06cc\u0627\u0628 \u062c\u0648\u0627\u0628 \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0631\u06cc\u06a9\u0627\u0631\u0688\u0632 \u06a9\u0648 \u0645\u062e\u062a\u0644\u0641 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u062a\u0631\u062a\u06cc\u0628 \u062f\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u060c \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u0645\u062e\u062a\u0644\u0641 \u062a\u0631\u062a\u06cc\u0628 \u0645\u06cc\u06ba \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u06cc\u0627 \u0646\u0642\u0644 \u0645\u06a9\u0627\u0646\u06cc \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u063a\u06cc\u0631 \u062f\u0633\u062a\u0627\u0648\u06cc\u0632\u06cc \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0642\u0648\u0627\u0639\u062f \u0636\u0627\u0626\u0639 \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u06cc\u06c1\u06cc \u0648\u062c\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u06c1\u0645 \u0645\u06cc\u0631\u0627\u062b\u06cc \u06c1\u062c\u0631\u062a \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u062b\u0628\u0648\u062a \u06a9\u0627 \u0627\u06cc\u06a9 \u0627\u0648\u0631 \u0630\u0631\u06cc\u0639\u06c1 \u067e\u0633\u0646\u062f \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 <strong>\u067e\u0631\u0627\u0646\u06d2 \u0627\u0648\u0631 \u0646\u0626\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0686\u0644\u0627\u0626\u06cc\u06ba \u0627\u0648\u0631 \u0646\u062a\u0627\u0626\u062c \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/strong><\/p>\n<p>\u06cc\u06c1 \u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u06a9\u0627 \u0628\u0646\u06cc\u0627\u062f\u06cc \u062e\u06cc\u0627\u0644 \u06c1\u06d2\u06d4 \u0635\u0631\u0641 \u06cc\u06c1 \u067e\u0648\u0686\u06be\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2 \u06a9\u06c1 \u0622\u06cc\u0627 \u0646\u06cc\u0627 \u0633\u0633\u0679\u0645 \u0627\u0645\u062a\u062d\u0627\u0646 \u067e\u0627\u0633 \u06a9\u0631 \u06af\u06cc\u0627 \u06c1\u06d2\u060c \u0622\u067e \u06cc\u06c1 \u0628\u06be\u06cc \u067e\u0648\u0686\u06be\u062a\u06d2 \u06c1\u06cc\u06ba: \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u0627\u0646 \u067e\u0679 \u06a9\u0648 \u062f\u06cc\u06a9\u06be\u062a\u06d2 \u06c1\u0648\u0626\u06d2\u060c \u0646\u06cc\u0627 \u0633\u0633\u0679\u0645 \u067e\u0631\u0627\u0646\u06d2 \u0633\u0633\u0679\u0645 \u0633\u06d2 \u0645\u062e\u062a\u0644\u0641 \u06a9\u06c1\u0627\u06ba \u0628\u0631\u062a\u0627\u0624 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u061f<\/p>\n<p>\u0641\u0631\u0642 \u062b\u0628\u0648\u062a \u06c1\u06d2\u06d4<\/p>\n<p>\u06a9\u0686\u06be \u06a9\u06cc\u0691\u06d2 \u06c1\u06cc\u06ba\u060c \u06a9\u0686\u06be \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u06a9\u06cc \u06af\u0626\u06cc \u0628\u06c1\u062a\u0631\u06cc \u06c1\u06cc\u06ba\u060c \u06a9\u0686\u06be \u0628\u06d2 \u0636\u0631\u0631 \u0627\u0638\u06c1\u0627\u0631 \u06a9\u06d2 \u0641\u0631\u0642 \u06c1\u06cc\u06ba\u060c \u0627\u0648\u0631 \u06a9\u0686\u06be \u0627\u06cc\u0633\u06d2 \u0631\u0648\u06cc\u06d2 \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u062c\u0633 \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u06a9\u0648\u0626\u06cc \u0646\u06c1\u06cc\u06ba \u062c\u0627\u0646\u062a\u0627 \u062a\u06be\u0627\u06d4<\/p>\n<p>\u06cc\u06c1 \u0679\u06cc\u0648\u0679\u0648\u0631\u06cc\u0644 \u062f\u06a9\u06be\u0627\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679\u0646\u06af \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc\u0633\u06d2 \u06a9\u0631\u06cc\u06ba:<\/p>\n<ul>\n<li>\n<p>\u067e\u0631\u0627\u0646\u06d2 \u0627\u0648\u0631 \u0646\u0626\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1<\/p>\n<\/li>\n<li>\n<p>\u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u06a9\u06cc\u0627 \u0645\u0633\u0627\u0648\u06cc \u0633\u0645\u062c\u06be\u0627 \u062c\u0627\u0646\u0627 \u0686\u0627\u06c1\u0626\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0627\u0633 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0622\u0624\u0679 \u067e\u0679 \u06a9\u0648 \u0645\u0639\u0645\u0648\u0644 \u0628\u0646\u0627\u0626\u06cc\u06ba<\/p>\n<\/li>\n<li>\n<p>\u0679\u0627\u0626\u0645 \u0627\u0633\u0679\u06cc\u0645\u067e \u0627\u0648\u0631 \u062f\u06cc\u06af\u0631 \u063a\u06cc\u0631 \u0645\u0642\u0631\u0631\u06c1 \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u06c1\u06cc\u0646\u0688\u0644 \u06a9\u0631\u0646\u0627<\/p>\n<\/li>\n<li>\n<p>\u063a\u0644\u0637\u06cc\u0648\u06ba \u0627\u0648\u0631 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1<\/p>\n<\/li>\n<li>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u062e\u0648\u062f \u0628\u062e\u0648\u062f \u0686\u0644\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u0631\u0648\u0627\u062f\u0627\u0631\u06cc \u06a9\u0648 \u0645\u062a\u0639\u0627\u0631\u0641 \u06a9\u0631\u0648\u0627\u0626\u06cc\u06ba \u062c\u06c1\u0627\u06ba \u0642\u0637\u0639\u06cc \u0645\u0633\u0627\u0648\u0627\u062a \u06a9\u0627 \u06a9\u0648\u0626\u06cc \u0645\u0637\u0644\u0628 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<li>\n<p>\u062a\u0636\u0627\u062f \u06a9\u0627 \u062a\u062c\u0632\u06cc\u06c1<\/p>\n<\/li>\n<li>\n<p>\u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0645\u06cc\u06ba \u0634\u06cc\u0688\u0648 \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u06c1\u0645 AI \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u062f\u0631\u0633\u062a\u06af\u06cc \u06a9\u0627 \u062a\u0639\u06cc\u0646 \u06a9\u06cc\u06d2 \u0628\u063a\u06cc\u0631 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u06cc \u062f\u0631\u062c\u06c1 \u0628\u0646\u062f\u06cc \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<\/li>\n<li>\n<p>\u062a\u0635\u062f\u06cc\u0642 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u06a9\u0679 \u0627\u0648\u0648\u0631 \u06a9\u06d2 \u0644\u06cc\u06d2 \u062a\u06cc\u0627\u0631 \u06c1\u06d2\u06d4<\/p>\n<\/li>\n<\/ul>\n<p>\u0645\u062b\u0627\u0644\u06cc\u06ba TypeScript \u0627\u0648\u0631 Vitest \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u062a\u06cc \u06c1\u06cc\u06ba\u060c \u0644\u06cc\u06a9\u0646 \u06cc\u06c1 \u0646\u0642\u0637\u06c1 \u0646\u0638\u0631 \u0632\u06cc\u0627\u062f\u06c1 \u062a\u0631 \u0632\u0628\u0627\u0646\u0648\u06ba \u0627\u0648\u0631 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06cc \u062d\u06a9\u0645\u062a \u0639\u0645\u0644\u06cc\u0648\u06ba \u067e\u0631 \u0644\u0627\u06af\u0648 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u0642\u0635\u062f \u06cc\u06c1 \u062b\u0627\u0628\u062a \u06a9\u0631\u0646\u0627 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u062f\u0627\u062e\u0644\u06cc \u0637\u0648\u0631 \u067e\u0631 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u06c1\u06cc\u06ba\u06d4 \u06cc\u06c1 \u062b\u0628\u0648\u062a \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u06cc\u06c1 \u0645\u0648\u062c\u0648\u062f \u06c1\u06d2\u06d4 <strong>\u0631\u0648\u06cc\u06d2 \u06a9\u06d2 \u0644\u062d\u0627\u0638 \u0633\u06d2 \u0645\u0633\u0627\u0648\u06cc \u062c\u0628 \u0645\u0633\u0627\u0648\u0627\u062a \u0627\u06c1\u0645 \u06c1\u0648\u06d4<\/strong>.<\/p>\n<h2 id=\"heading-prerequisites\">\u0634\u0631\u0637\u06cc\u06ba<\/h2>\n<p>\u0633\u0627\u062a\u06be \u0686\u0644\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2\u060c \u0622\u067e \u06a9\u0648 \u062f\u0631\u062c \u0630\u06cc\u0644 \u0633\u06d2 \u0648\u0627\u0642\u0641 \u06c1\u0648\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2:<\/p>\n<ul>\n<li>\n<p>TypeScript \u06cc\u0627 \u0627\u0633 \u0633\u06d2 \u0645\u0644\u062a\u06cc \u062c\u0644\u062a\u06cc \u0632\u0628\u0627\u0646<\/p>\n<\/li>\n<li>\n<p>\u06cc\u0648\u0646\u0679 \u0627\u0648\u0631 \u0627\u0646\u0636\u0645\u0627\u0645 \u06a9\u06cc \u062c\u0627\u0646\u0686<\/p>\n<\/li>\n<li>\n<p>\u063a\u06cc\u0631 \u0645\u0637\u0627\u0628\u0642\u062a \u067e\u0630\u06cc\u0631 \u06a9\u0648\u0688<\/p>\n<\/li>\n<li>\n<p>API \u0627\u0648\u0631 \u0633\u0631\u0648\u0633 \u06a9\u06cc \u062d\u062f\u0648\u062f<\/p>\n<\/li>\n<li>\n<p>\u0645\u06cc\u0631\u0627\u062b\u06cc \u062c\u062f\u06cc\u062f \u06a9\u0627\u0631\u06cc<\/p>\n<\/li>\n<li>\n<p>\u0628\u0646\u06cc\u0627\u062f\u06cc \u0645\u0634\u0627\u06c1\u062f\u0627\u062a\u06cc \u062a\u0635\u0648\u0631\u0627\u062a<\/p>\n<\/li>\n<\/ul>\n<p>\u0622\u067e \u06a9\u0648 \u067e\u06c1\u0644\u06d2 \u0633\u06d2 \u06c1\u06cc \u0645\u0646\u062a\u0642\u0644 \u06c1\u0648\u0646\u06d2 \u0648\u0627\u0644\u06cc \u062e\u0635\u0648\u0635\u06cc\u0627\u062a \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u06a9\u0686\u06be \u0633\u0645\u062c\u06be\u0646\u0627 \u0686\u0627\u06c1\u0626\u06d2\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644\u06cc \u0637\u0648\u0631 \u067e\u0631\u060c \u0622\u067e \u0627\u0646 \u067e\u0679\u0633\u060c \u0622\u0624\u0679 \u067e\u0679\u0633\u060c \u0627\u06c1\u0645 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0642\u0648\u0627\u0639\u062f\u060c \u0628\u06cc\u0631\u0648\u0646\u06cc \u0645\u0639\u0627\u06c1\u062f\u0648\u06ba\u060c \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a\u060c \u0627\u0648\u0631 \u063a\u06cc\u0631 \u06cc\u0642\u06cc\u0646\u06cc \u0635\u0648\u0631\u062a\u062d\u0627\u0644 \u06a9\u06d2 \u0645\u0639\u0644\u0648\u0645 \u0639\u0644\u0627\u0642\u0648\u06ba \u06a9\u0648 \u062c\u0627\u0646\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679\u0646\u06af \u0628\u06c1\u062a\u0631\u06cc\u0646 \u06a9\u0627\u0645 \u06a9\u0631\u062a\u06cc \u06c1\u06d2 \u062c\u0628 \u0622\u067e \u067e\u06c1\u0644\u06d2 \u0633\u06d2 \u06c1\u06cc \u0627\u0646 \u062e\u0635\u0648\u0635\u06cc\u0627\u062a \u06a9\u06d2 \u0627\u0631\u062f \u06af\u0631\u062f \u062d\u062f\u0648\u062f \u0628\u0646\u0627 \u0644\u06cc\u062a\u06d2 \u06c1\u06cc\u06ba \u062c\u0646\u06c1\u06cc\u06ba \u0622\u067e \u0645\u0646\u062a\u0642\u0644 \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-table-of-contents\">\u0627\u0646\u0688\u06cc\u06a9\u0633<\/h2>\n<h2 id=\"heading-what-differential-testing-actually-tells-you\">\u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u0648\u0627\u0642\u0639\u06cc \u06c1\u0645\u06cc\u06ba \u06a9\u06cc\u0627 \u0628\u062a\u0627\u062a\u06cc \u06c1\u06d2\u06d4<\/h2>\n<p>\u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u06cc \u0645\u0648\u062c\u0648\u062f\u06c1 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0633\u06cc \u0622\u0631\u0688\u0631 \u06a9\u06cc \u062d\u062a\u0645\u06cc \u0642\u06cc\u0645\u062a \u06a9\u0627 \u062d\u0633\u0627\u0628 \u0644\u06af\u0627\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u06cc\u0631\u0627\u062b \u06a9\u0627 \u0646\u0641\u0627\u0630 \u06cc\u06c1 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">type Order = {\n  subtotal: number;\n  customerType: \"STANDARD\" | \"PREMIUM\";\n  country: string;\n};\n\nfunction legacyCalculateTotal(order: Order): number {\n  let total = order.subtotal;\n\n  if (order.customerType === \"PREMIUM\") {\n    total *= 0.9;\n  }\n\n  if (order.country === \"AR\") {\n    total -= 500;\n  }\n\n  return Math.max(total, 0);\n}\n<\/code><\/pre>\n<p>\u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0628\u0646\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-typescript\">function newCalculateTotal(order: Order): number {\n  const premiumDiscount =\n    order.customerType === \"PREMIUM\"\n      ? order.subtotal * 0.1\n      : 0;\n\n  const countryAdjustment =\n    order.country === \"AR\"\n      ? 500\n      : 0;\n\n  return Math.max(\n    order.subtotal -\n      premiumDiscount -\n      countryAdjustment,\n    0\n  );\n}\n<\/code><\/pre>\n<p>\u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u0645\u062e\u062a\u0644\u0641 \u0646\u0638\u0631 \u0622\u062a\u0627 \u06c1\u06d2\u06d4 \u0627\u0648\u0631 \u06cc\u06c1 \u0679\u06be\u06cc\u06a9 \u06c1\u06d2\u06d4 \u0627\u06c1\u0645 \u0628\u0627\u062a \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0622\u06cc\u0627 \u0648\u06c1 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u0627 \u0633\u0644\u0648\u06a9 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0633\u0627\u062f\u06c1 \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u062f\u0648\u0646\u0648\u06ba \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">import { describe, expect, it } from \"vitest\";\n\ndescribe(\"order total migration\", () => {\n  it(\"matches the legacy implementation\", () => {\n    const order: Order = {\n      subtotal: 10000,\n      customerType: \"PREMIUM\",\n      country: \"AR\",\n    };\n\n    const legacy =\n      legacyCalculateTotal(order);\n\n    const migrated =\n      newCalculateTotal(order);\n\n    expect(migrated).toBe(legacy);\n  });\n});\n<\/code><\/pre>\n<p>\u0627\u0633 \u0627\u0646 \u067e\u0679 \u06a9\u06d2 \u0644\u06cc\u06d2:<\/p>\n<pre><code class=\"language-text\">legacy \u2192 8500\nnew    \u2192 8500\n<\/code><\/pre>\n<p>\u0627\u0686\u06be\u0627 \u062a\u0627\u06c1\u0645\u060c \u0645\u06cc\u0686 \u06a9\u06cc \u0627\u06cc\u06a9 \u0645\u062b\u0627\u0644 \u0634\u0627\u0630 \u0648 \u0646\u0627\u062f\u0631 \u06c1\u06cc \u062b\u0627\u0628\u062a \u06c1\u0648\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0642\u062f\u0631 \u0645\u0646\u0638\u0645 \u0633\u0648\u0627\u0644\u0627\u062a \u0633\u06d2 \u0622\u062a\u06cc \u06c1\u06d2 \u062c\u06cc\u0633\u06d2:<\/p>\n<pre><code class=\"language-text\">same input\n\u2193\nlegacy implementation \u2500\u2500\u2192 result A\n\nsame input\n\u2193\nnew implementation \u2500\u2500\u2500\u2500\u2500\u2192 result B\n\ncompare A and B\n<\/code><\/pre>\n<p>\u06a9\u0648\u0626\u06cc \u0628\u06be\u06cc \u062a\u0636\u0627\u062f \u0622\u067e \u06a9\u0648 \u062a\u062d\u0642\u06cc\u0642\u0627\u062a \u06a9\u06d2 \u0644\u06cc\u06d2 \u06a9\u0686\u06be \u062f\u06cc\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-start-with-one-observable-boundary\">\u0627\u06cc\u06a9 \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u062d\u062f \u0633\u06d2 \u0634\u0631\u0648\u0639 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u067e\u0648\u0631\u06cc \u0627\u06cc\u067e\u0644\u06cc \u06a9\u06cc\u0634\u0646\u0632 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06a9\u06d2 \u0634\u0631\u0648\u0639 \u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4 \u0634\u0631\u0648\u0639 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0627\u06cc\u06a9 \u062e\u0635\u0648\u0635\u06cc\u062a \u0645\u0646\u062a\u062e\u0628 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">Calculate Order Total\nGenerate Invoice\nApprove Customer\nRenew Subscription\nCalculate Commission\nCreate Shipment\n<\/code><\/pre>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06cc \u062d\u062f \u06cc\u06c1 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">interface OrderProcessor {\n  process(order: Order): Promise<processedorder>;\n}\n<\/processedorder><\/code><\/pre>\n<p>\u0627\u0628 \u062f\u0648 \u0646\u0641\u0627\u0630 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">LegacyOrderProcessor\n\nNewOrderProcessor\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u0627\u06cc\u06a9 \u0645\u0641\u06cc\u062f \u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062d\u062f \u06c1\u06d2 \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0627\u06cc\u06a9 \u06c1\u06cc \u062a\u0635\u0648\u0631\u0627\u062a\u06cc \u0627\u0646 \u067e\u0679 \u062d\u0627\u0635\u0644 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u0627\u06cc\u06a9 \u06c1\u06cc \u062a\u0635\u0648\u0631\u0627\u062a\u06cc \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u0648\u0627\u0632\u0646\u06c1 \u062f\u0627\u062e\u0644\u06cc \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u0633\u06d2 \u0645\u0645\u0627\u062b\u0644 \u06a9\u06cc\u06d2 \u0628\u063a\u06cc\u0631 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06c1\u062c\u0631\u062a \u0627\u06c1\u0645 \u06c1\u06d2 \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u0627\u0633 \u0645\u06cc\u06ba \u0627\u06a9\u062b\u0631 \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u0633\u0627\u062e\u062a\u06cc \u062a\u0628\u062f\u06cc\u0644\u06cc\u0627\u06ba \u0634\u0627\u0645\u0644 \u06c1\u0648\u062a\u06cc \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u06cc\u0631\u0627\u062b \u06a9\u0627 \u0646\u0641\u0627\u0630 \u06cc\u06c1 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">controller\n\u2192 service\n\u2192 SQL\n\u2192 provider SDK\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u06cc\u06c1 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">use case\n\u2192 repository\n\u2192 gateway\n\u2192 events\n<\/code><\/pre>\n<p>\u0622\u067e \u06a9\u0648 \u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u0641\u06a9\u0631 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u06c1\u0645\u06cc\u06ba \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u0631\u0648\u06cc\u06d2 \u0645\u06cc\u06ba \u062f\u0644\u0686\u0633\u067e\u06cc \u0644\u06cc\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-run-the-legacy-and-new-implementations-with-the-same-input\">\u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u067e\u0631\u0627\u0646\u06d2 \u0627\u0648\u0631 \u0646\u0626\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0686\u0644\u0627\u0626\u06cc\u06ba\u06d4<\/h2>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0628\u06d2 \u0646\u0642\u0627\u0628 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">interface OrderProcessor {\n  process(order: Order): Promise<processedorder>;\n}\n<\/processedorder><\/code><\/pre>\n<p>\u0622\u067e \u062a\u0634\u06a9\u06cc\u0644 \u062f\u06d2 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">const legacyProcessor =\n  new LegacyOrderProcessor();\n\nconst newProcessor =\n  new NewOrderProcessor();\n<\/code><\/pre>\n<p>\u067e\u06be\u0631:<\/p>\n<pre><code class=\"language-typescript\">it(\"produces the same processed order\", async () => {\n  const input: Order = {\n    id: \"order-1\",\n    subtotal: 10000,\n    customerType: \"PREMIUM\",\n    country: \"US\",\n  };\n\n  const legacy =\n    await legacyProcessor.process(\n      structuredClone(input)\n    );\n\n  const migrated =\n    await newProcessor.process(\n      structuredClone(input)\n    );\n\n  expect(migrated).toEqual(legacy);\n});\n<\/code><\/pre>\n<p>\u06a9\u06d2 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0648 \u0646\u0648\u0679 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">structuredClone(input)\n<\/code><\/pre>\n<p>\u0627\u06af\u0631 \u0622\u067e \u06a9\u06d2 \u0646\u0641\u0627\u0630 \u0645\u06cc\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u0627\u0646 \u067e\u0679 \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062a\u0648 \u06cc\u06c1 \u0627\u06c1\u0645 \u06c1\u06d2\u06d4<\/p>\n<p>\u0639\u0644\u06cc\u062d\u062f\u06c1 \u06a9\u0627\u067e\u06cc \u06a9\u06d2 \u0628\u063a\u06cc\u0631\u060c \u067e\u06c1\u0644\u06cc \u0631\u0646 \u062f\u0648\u0633\u0631\u06cc \u0631\u0646 \u06a9\u0648 \u0645\u062a\u0627\u062b\u0631 \u06a9\u0631 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u067e \u06a9\u06cc\u0627 \u0686\u0627\u06c1\u062a\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">same initial state\n<\/code><\/pre>\n<p>\u0646\u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">new implementation receives state modified by legacy implementation\n<\/code><\/pre>\n<p>\u0627\u0633 \u0642\u0633\u0645 \u06a9\u06cc \u0622\u0644\u0648\u062f\u06af\u06cc \u063a\u0644\u0637 \u0646\u062a\u0627\u0626\u062c \u06a9\u0627 \u0628\u0627\u0639\u062b \u0628\u0646 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-dont-compare-raw-output-blindly\">\u062e\u0627\u0645 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u06a9\u0627 \u0622\u0646\u06a9\u06be \u0628\u0646\u062f \u06a9\u0631 \u06a9\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u06a9\u0627 \u067e\u06c1\u0644\u0627 \u0648\u0631\u0698\u0646 \u062f\u0631\u062c \u0630\u06cc\u0644 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">expect(newResult).toEqual(legacyResult);\n<\/code><\/pre>\n<p>\u06a9\u0628\u06be\u06cc \u06a9\u0628\u06be\u06cc \u06cc\u06c1 \u0628\u0627\u0644\u06a9\u0644 \u0635\u062d\u06cc\u062d \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u06d4 \u0644\u06cc\u06a9\u0646 \u062f\u0648\u0633\u0631\u06cc \u0628\u0627\u0631 \u0645\u06cc\u06ba \u063a\u0644\u0637 \u06c1\u0648\u06ba\u06d4<\/p>\n<p>\u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u06a9\u06cc \u0648\u0627\u067e\u0633\u06cc \u06a9\u0627 \u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-json\">{\n  \"id\": \"order-1\",\n  \"total\": 9000,\n  \"status\": \"PROCESSED\",\n  \"generatedAt\": \"2026-09-09T10:00:01.231Z\",\n  \"requestId\": \"legacy-f93a\"\n}\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0646\u0638\u0627\u0645 \u0648\u0627\u067e\u0633 \u0622\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-json\">{\n  \"requestId\": \"new-b517\",\n  \"status\": \"PROCESSED\",\n  \"generatedAt\": \"2026-09-09T10:00:01.416Z\",\n  \"total\": 9000,\n  \"id\": \"order-1\"\n}\n<\/code><\/pre>\n<p>\u062e\u0627\u0645 \u0622\u0628\u062c\u06cc\u06a9\u0679 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u062f\u0631\u062c \u0630\u06cc\u0644 \u0648\u062c\u0648\u06c1\u0627\u062a \u06a9\u06cc \u0628\u0646\u0627\u0621 \u067e\u0631 \u0646\u0627\u06a9\u0627\u0645 \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-text\">requestId differs\ntimestamp differs\n<\/code><\/pre>\n<p>\u062a\u0627\u06c1\u0645\u060c \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0631\u0648\u06cc\u06c1 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u0627 \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u067e \u06a9\u0648 \u06cc\u06c1 \u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2 \u06a9\u06c1 \u06a9\u0648\u0646 \u0633\u06d2 \u0641\u06cc\u0644\u0688\u0632 \u0628\u0627\u0645\u0639\u0646\u06cc \u0645\u0639\u0627\u06c1\u062f\u06d2 \u06a9\u0627 \u062d\u0635\u06c1 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0634\u0627\u06cc\u062f:<\/p>\n<pre><code class=\"language-text\">id\ntotal\nstatus\n<\/code><\/pre>\n<p>\u0645\u0633\u0626\u0644\u06c1<\/p>\n<p>\u062c\u0628\u06a9\u06c1:<\/p>\n<pre><code class=\"language-text\">generatedAt\nrequestId\n<\/code><\/pre>\n<p>\u0642\u0637\u0639\u06cc \u0645\u0633\u0627\u0648\u0627\u062a \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u0645\u0639\u0645\u0648\u0644 \u06a9\u06cc \u0637\u0631\u0641 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-normalize-values-before-comparing-them\">\u0627\u0646 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u0645\u0639\u0645\u0648\u0644 \u0628\u0646\u0627\u0626\u06cc\u06ba<\/h2>\n<p>\u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u06cc\u0634\u0646 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2 \u06a9\u06c1 \u0627\u0646 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0622\u0624\u0679 \u067e\u0679 \u06a9\u0648 \u0645\u0634\u062a\u0631\u06a9\u06c1 \u0646\u0645\u0627\u0626\u0646\u062f\u06af\u06cc \u0645\u06cc\u06ba \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u0646\u0627\u06d4<\/p>\n<p>\u0645\u0642\u0635\u062f \u0688\u06cc\u0679\u0627 \u06a9\u06d2 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0645\u0639\u0646\u06cc \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u0646\u0627 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u062e\u06cc\u0627\u0644 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0627\u0646 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u0648 \u062f\u0648\u0631 \u06a9\u06cc\u0627 \u062c\u0627\u0626\u06d2 \u062c\u0648 \u0645\u062a\u0648\u0642\u0639 \u06c1\u06cc\u06ba \u0644\u06cc\u06a9\u0646 \u0645\u0648\u0627\u0632\u0646\u06c1 \u0633\u06d2 \u0645\u062a\u0639\u0644\u0642 \u0646\u06c1\u06cc\u06ba \u06c1\u06cc\u06ba\u060c \u062c\u06cc\u0633\u06d2 \u06a9\u06c1 \u062a\u06cc\u0627\u0631 \u06a9\u0631\u062f\u06c1 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u06cc IDs \u06cc\u0627 \u0679\u0627\u0626\u0645 \u0627\u0633\u0679\u06cc\u0645\u067e\u060c \u062a\u0627\u06a9\u06c1 \u0622\u067e \u0627\u067e\u0646\u06cc \u062c\u0627\u0646\u0686 \u06a9\u0648 \u0627\u0646 \u0641\u06cc\u0644\u0688\u0632 \u067e\u0631 \u0645\u0631\u06a9\u0648\u0632 \u06a9\u0631 \u0633\u06a9\u06cc\u06ba \u062c\u0648 \u062f\u0631\u0627\u0635\u0644 \u062f\u0644\u0686\u0633\u067e\u06cc \u06a9\u06d2 \u0631\u0648\u06cc\u06d2 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0639\u0645\u0644\u06cc \u0637\u0648\u0631 \u067e\u0631\u060c \u0627\u0633 \u06a9\u0627 \u0627\u06a9\u062b\u0631 \u0645\u0637\u0644\u0628 \u06c1\u0648\u062a\u0627 \u06c1\u06d2 \u0627\u06cc\u06a9 \u0645\u0639\u06cc\u0627\u0631\u06cc \u0646\u0645\u0627\u0626\u0646\u062f\u06af\u06cc\u060c \u0627\u06cc\u06a9 \u0686\u06be\u0648\u0679\u06cc\u060c \u0632\u06cc\u0627\u062f\u06c1 \u0645\u0633\u062a\u062d\u06a9\u0645 \u0634\u06a9\u0644 \u062c\u0633 \u0645\u06cc\u06ba \u0635\u0631\u0641 \u0648\u06c1\u06cc \u0645\u0639\u0646\u06cc \u062e\u06cc\u0632 \u0641\u06cc\u0644\u0688\u0632 \u06c1\u0648\u06ba \u062c\u0646 \u06a9\u0627 \u0622\u067e \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-typescript\">type ProcessedOrder = {\n  id: string;\n  total: number;\n  status: string;\n  generatedAt: string;\n  requestId: string;\n};\n\nfunction normalizeOrder(\n  order: ProcessedOrder\n) {\n  return {\n    id: order.id,\n    total: order.total,\n    status: order.status,\n  };\n}\n<\/code><\/pre>\n<p>\u06cc\u06c1\u0627\u06ba\u060c <code>ProcessedOrder<\/code> \u06a9\u0627\u0631\u0648\u0628\u0627\u0631 \u0633\u06d2 \u0645\u062a\u0639\u0644\u0642\u06c1 \u062a\u0645\u0627\u0645 \u0641\u06cc\u0644\u0688\u0632 \u0627\u0648\u0631 \u0627\u0642\u062f\u0627\u0631 \u0634\u0627\u0645\u0644 \u06c1\u06cc\u06ba \u062c\u0648 \u0642\u0627\u0646\u0648\u0646\u06cc \u0637\u0648\u0631 \u067e\u0631 \u0627\u06cc\u06a9 \u062f\u0648\u0633\u0631\u06d2 \u0633\u06d2 \u0686\u0644\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0645\u062e\u062a\u0644\u0641 \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u06a9\u06c1 <code>normalizeOrder()<\/code> \u0641\u0646\u06a9\u0634\u0646 \u0628\u0631\u0642\u0631\u0627\u0631 \u06c1\u06d2 <code>id<\/code>, <code>total<\/code>\u0627\u0648\u0631 <code>status<\/code>\u0628\u0627\u06c1\u0631 \u0646\u06a9\u0644\u062a\u06d2 \u0648\u0642\u062a <code>generatedAt<\/code> \u0627\u0648\u0631 <code>requestId<\/code>. \u0627\u0633 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u06cc\u06c1\u0627\u06ba \u062a\u06a9 \u06a9\u06c1 \u0627\u06af\u0631 \u062f\u0648 \u0646\u062a\u0627\u0626\u062c \u0642\u062f\u0631\u06d2 \u0645\u062e\u062a\u0644\u0641 \u0627\u0648\u0642\u0627\u062a \u0645\u06cc\u06ba \u0628\u0646\u0627\u0626\u06d2 \u06af\u0626\u06d2 \u06c1\u0648\u06ba \u06cc\u0627 \u0645\u062e\u062a\u0644\u0641 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u06d2 \u0634\u0646\u0627\u062e\u062a \u06a9\u0646\u0646\u062f\u06af\u0627\u0646 \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u060c \u062a\u0628 \u0628\u06be\u06cc \u0627\u0646\u06c1\u06cc\u06ba \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u0627 \u0633\u0645\u062c\u06be\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u0628 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">expect(\n  normalizeOrder(migrated)\n).toEqual(\n  normalizeOrder(legacy)\n);\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u0645\u0633\u0627\u0648\u0627\u062a \u06a9\u06d2 \u0627\u0635\u0648\u0644 \u06a9\u0648 \u0648\u0627\u0636\u062d \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u067e \u06a9\u06c1\u06c1 \u0631\u06c1\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<blockquote>\n<p>\u06cc\u06c1 \u0641\u06cc\u0644\u0688\u0632 \u0627\u0633 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u062a\u0639\u0644\u0642\u06c1 \u0631\u0648\u06cc\u06d2 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u062a\u06cc \u06c1\u06cc\u06ba\u06d4<\/p>\n<\/blockquote>\n<p>\u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u06cc\u0634\u0646 \u0628\u06be\u06cc \u0633\u0646\u0628\u06be\u0627\u0644 \u0633\u06a9\u062a\u06cc \u06c1\u06d2:<\/p>\n<p>\u062a\u0627\u06c1\u0645\u060c \u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u06cc\u0634\u0646 \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u06c1\u0648\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2\u06d4 \u0628\u06c1\u062a \u0632\u06cc\u0627\u062f\u06c1 \u06c1\u0679\u0627\u0646\u06d2 \u0633\u06d2 \u0646\u0642\u0644 \u0645\u06a9\u0627\u0646\u06cc \u06a9\u06d2 \u062d\u0642\u06cc\u0642\u06cc \u06a9\u06cc\u0691\u06d2 \u0686\u06be\u067e \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-handle-timestamps-and-other-nondeterministic-values\">\u0679\u0627\u0626\u0645 \u0627\u0633\u0679\u06cc\u0645\u067e \u0627\u0648\u0631 \u062f\u06cc\u06af\u0631 \u063a\u06cc\u0631 \u0645\u0642\u0631\u0631\u06c1 \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u06c1\u06cc\u0646\u0688\u0644 \u06a9\u0631\u0646\u0627<\/h2>\n<p>\u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u0645\u06cc\u06ba \u0628\u06c1\u062a \u0633\u06cc \u063a\u06cc\u0631 \u0645\u062a\u0639\u06cc\u0646 \u0627\u0642\u062f\u0627\u0631 \u06c1\u0648\u062a\u06cc \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">timestamps\nUUIDs\nrandom tokens\nrequest IDs\ntrace IDs\ndatabase-generated IDs\nunordered collections\nprovider-generated references\n<\/code><\/pre>\n<p>\u0627\u0646 \u0627\u0642\u062f\u0627\u0631 \u06a9\u0627 \u0639\u06cc\u0646 \u0645\u0637\u0627\u0628\u0642 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u0627 \u062a\u0641\u0631\u06cc\u0642 \u0648\u0627\u0644\u06d2 \u062e\u0627\u0646\u062f\u0627\u0646\u0648\u06ba \u06a9\u0648 \u0645\u0633\u0644\u0633\u0644 \u0646\u0627\u06a9\u0627\u0645 \u06c1\u0648\u0646\u06d2 \u06a9\u0627 \u0633\u0628\u0628 \u0628\u0646 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0622\u067e\u0634\u0646 \u0627\u0646\u062d\u0635\u0627\u0631 \u06a9\u0646\u0679\u0631\u0648\u0644 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u0646\u062d\u0635\u0627\u0631 \u06a9\u06d2 \u06a9\u0646\u0679\u0631\u0648\u0644 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2 \u063a\u06cc\u0631 \u0645\u062a\u0639\u06cc\u0646 \u0630\u0631\u0627\u0626\u0639 \u06a9\u0648 \u0645\u0646\u062a\u0642\u0644 \u06a9\u0631\u0646\u0627\u060c \u062c\u06cc\u0633\u06d2 \u0645\u0648\u062c\u0648\u062f\u06c1 \u0648\u0642\u062a \u06cc\u0627 ID \u062c\u0646\u0631\u06cc\u0679\u0631\u060c \u0627\u06cc\u06a9 \u0627\u0646\u0679\u0631\u0641\u06cc\u0633 \u06a9\u06d2 \u067e\u06cc\u0686\u06be\u06d2 \u062c\u06c1\u0627\u06ba \u0627\u0646\u06c1\u06cc\u06ba \u062c\u0627\u0646\u0686 \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06c1\u0631 \u0639\u0645\u0644 \u06a9\u0648 \u0627\u0635\u0644 \u06af\u06be\u0691\u06cc \u06a9\u0648 \u0622\u0632\u0627\u062f\u0627\u0646\u06c1 \u0637\u0648\u0631 \u067e\u0631 \u067e\u0691\u06be\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2\u060c \u06c1\u0645 \u062f\u0648\u0646\u0648\u06ba \u0645\u06cc\u06ba \u0627\u06cc\u06a9 \u06c1\u06cc \u06a9\u0646\u0679\u0631\u0648\u0644 \u06af\u06be\u0691\u06cc \u0644\u06af\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0627\u0633 \u0633\u06d2 \u0627\u0646\u06c1\u06cc\u06ba \u06cc\u06a9\u0633\u0627\u06ba \u0642\u062f\u0631 \u0645\u0644\u062a\u06cc \u06c1\u06d2 \u0627\u0648\u0631 \u0648\u0642\u062a \u06a9\u0648 \u062e\u0648\u062f \u06c1\u06cc \u0628\u06d2 \u0645\u0639\u0646\u06cc \u0627\u062e\u0631\u0627\u062c \u06a9\u0627 \u0630\u0631\u06cc\u0639\u06c1 \u0628\u0646\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u0627 \u06a9\u0648\u0688 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">new Date()\n<\/code><\/pre>\n<p>\u0622\u067e \u0627\u0633 \u0627\u0646\u062d\u0635\u0627\u0631 \u06a9\u0648 \u06af\u06be\u0691\u06cc \u0633\u06d2 \u0628\u062f\u0644 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-typescript\">interface Clock {\n  now(): Date;\n}\n<\/code><\/pre>\n<p>\u067e\u06be\u0631 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0645\u0648\u0635\u0648\u0644 \u06c1\u0648\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">const clock = {\n  now: () =>\n    new Date(\n      \"2026-09-09T10:00:00.000Z\"\n    ),\n};\n<\/code><\/pre>\n<p>\u0627\u0628 \u0648\u0642\u062a \u0645\u0633\u062a\u0642\u0644 \u0637\u0648\u0631 \u067e\u0631 \u0628\u062f\u0644\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u0626\u06cc \u0688\u06cc \u0628\u0646\u0627\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0628\u06be\u06cc \u06cc\u06c1\u06cc \u062a\u06a9\u0646\u06cc\u06a9 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc \u062c\u0627 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-typescript\">interface IdGenerator {\n  next(): string;\n}\n<\/code><\/pre>\n<p>\u067e\u06be\u0631 \u0679\u06cc\u0633\u0679 \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">const ids = {\n  next: () => \"fixed-id\",\n};\n<\/code><\/pre>\n<p>\u0627\u06af\u0631 \u0639\u062f\u0645 \u0627\u0633\u062a\u062d\u06a9\u0627\u0645 \u067e\u0631 \u0642\u0627\u0628\u0648 \u067e\u0627\u0646\u0627 \u0646\u0627\u0642\u0627\u0628\u0644 \u0639\u0645\u0644 \u06c1\u06d2\u060c \u062a\u0648 \u0627\u0633\u06d2 \u0635\u0631\u0641 \u0627\u0633 \u0635\u0648\u0631\u062a \u0645\u06cc\u06ba \u0645\u0639\u0645\u0648\u0644 \u0628\u0646\u0627\u0626\u06cc\u06ba \u062c\u0628 \u06cc\u06c1 \u0627\u0633 \u0637\u0631\u0632 \u0639\u0645\u0644 \u06a9\u0627 \u062d\u0635\u06c1 \u0646\u06c1 \u06c1\u0648 \u062c\u0633 \u06a9\u06cc \u0622\u067e \u06a9\u0648 \u062d\u0641\u0627\u0638\u062a \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-compare-business-meaning-not-just-json\">\u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0633\u06cc\u0645\u0646\u0679\u06a9\u0633 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u0627\u060c \u0646\u06c1 \u0635\u0631\u0641 JSON<\/h2>\n<p>\u062f\u0648 \u0646\u0638\u0627\u0645 \u0627\u06cc\u06a9 \u06c1\u06cc \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0631\u06cc\u0627\u0633\u062a \u06a9\u06cc \u0646\u0645\u0627\u0626\u0646\u062f\u06af\u06cc \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba \u0644\u06cc\u06a9\u0646 \u0645\u062e\u062a\u0644\u0641 \u0646\u0645\u0627\u0626\u0646\u062f\u06af\u06cc\u06cc\u06ba \u0648\u0627\u067e\u0633 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u06d2 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u0645\u06cc\u06ba \u062f\u0631\u062c \u0630\u06cc\u0644 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-json\">{\n  \"status\": 2\n}\n<\/code><\/pre>\n<p>\u0646\u0626\u06cc \u0645\u0635\u0646\u0648\u0639\u0627\u062a \u0645\u06cc\u06ba \u0634\u0627\u0645\u0644 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-json\">{\n  \"status\": \"APPROVED\"\n}\n<\/code><\/pre>\n<p>\u062e\u0627\u0645 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06c1\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">different\n<\/code><\/pre>\n<p>\u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0645\u0648\u0627\u0632\u0646\u06c1 \u0627\u0633 \u0637\u0631\u062d \u06a9\u06c1\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">equivalent\n<\/code><\/pre>\n<p>\u0622\u067e \u0633\u06cc\u0645\u0646\u0679\u06a9 \u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u06cc\u0634\u0646 \u0679\u0648\u0644 \u0628\u0646\u0627 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-typescript\">function normalizeStatus(\n  status: number | string\n) {\n  if (status === 2) {\n    return \"APPROVED\";\n  }\n\n  return status;\n}\n<\/code><\/pre>\n<p>\u06cc\u06c1\u0627\u06ba \u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u0631 \u0645\u0648\u062c\u0648\u062f\u06c1 \u0639\u062f\u062f\u06cc \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 <code>2<\/code> \u0646\u0626\u06d2 \u0646\u0641\u0627\u0630 \u0645\u06cc\u06ba \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06c1\u0648\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0645\u0639\u0646\u06cc \u06a9\u06d2 \u0633\u0627\u062a\u06be: <code>\"APPROVED\"<\/code>.<\/p>\n<p>\u0645\u06cc\u06ba \u06cc\u06c1 \u062f\u0639\u0648\u06cc \u0646\u06c1\u06cc\u06ba \u06a9\u0631 \u0631\u06c1\u0627 \u06c1\u0648\u06ba \u06a9\u06c1 \u062a\u0645\u0627\u0645 \u0646\u0645\u0628\u0631\u0632 \u0627\u0648\u0631 \u0633\u0679\u0631\u0646\u06af\u0632 \u0642\u0627\u0628\u0644 \u062a\u0628\u0627\u062f\u0644\u06c1 \u06c1\u06cc\u06ba\u06d4 \u06cc\u06c1 \u0627\u06cc\u06a9 \u0648\u0627\u0636\u062d \u0645\u0633\u0627\u0648\u06cc \u0627\u0635\u0648\u0644 \u06a9\u0648 \u0627\u0646\u06a9\u0648\u0688 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062c\u0633\u06d2 \u06c1\u0645 \u0646\u06d2 \u067e\u06c1\u0644\u06d2 \u06c1\u06cc \u0627\u0633 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u0644\u06cc\u06d2 \u062f\u0631\u0633\u062a \u0642\u0631\u0627\u0631 \u062f\u06d2 \u062f\u06cc\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u067e\u06be\u0631:<\/p>\n<pre><code class=\"language-typescript\">expect(\n  normalizeStatus(newResult.status)\n).toBe(\n  normalizeStatus(legacyResult.status)\n);\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u062e\u0627\u0635 \u0637\u0648\u0631 \u067e\u0631 \u0645\u0641\u06cc\u062f \u06c1\u06d2 \u062c\u0628 \u0646\u0642\u0644 \u0645\u06a9\u0627\u0646\u06cc \u06a9\u06cc \u062a\u0628\u062f\u06cc\u0644\u06cc\u0627\u06ba \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u06c1\u0648\u06ba\u06d4<\/p>\n<pre><code class=\"language-text\">database schema\nAPI representation\nenumerations\nprovider-specific formats\ninternal identifiers\n<\/code><\/pre>\n<p>\u0627\u06c1\u0645 \u0633\u0648\u0627\u0644\u0627\u062a \u06cc\u06c1 \u06c1\u06cc\u06ba:<\/p>\n<blockquote>\n<p>\u06a9\u06cc\u0627 \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0645\u0636\u0645\u0631\u0627\u062a \u0648\u06c1\u06cc \u0631\u06c1\u06cc\u06ba \u06af\u06d2\u061f<\/p>\n<\/blockquote>\n<p>\u0646\u06c1\u06cc\u06ba:<\/p>\n<blockquote>\n<p>\u06a9\u06cc\u0627 \u0628\u0627\u0626\u0679\u0633 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u06c1\u06cc\u06ba\u061f<\/p>\n<\/blockquote>\n<h2 id=\"heading-compare-errors-as-part-of-the-contract\">\u0645\u0639\u0627\u06c1\u062f\u06d2 \u06a9\u06d2 \u062d\u0635\u06d2 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u062e\u0631\u0627\u0628\u06cc \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1<\/h2>\n<p>\u06a9\u0627\u0645\u06cc\u0627\u0628\u06cc \u06a9\u0627 \u0631\u062f\u0639\u0645\u0644 \u067e\u0648\u0631\u06cc \u06a9\u0627\u0631\u0631\u0648\u0627\u0626\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4 \u063a\u0644\u0637\u06cc\u0627\u06ba \u0628\u06be\u06cc \u0627\u06c1\u0645 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u0627 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0641\u0627\u0630 \u0644\u0627\u067e\u062a\u06c1 \u0635\u0627\u0631\u0641\u06cc\u0646 \u06a9\u0648 \u0645\u0633\u062a\u0631\u062f \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-typescript\">throw new Error(\"Customer not found\");\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u063a\u0644\u0637\u06cc \u0633\u06d2 \u0648\u0627\u067e\u0633 \u0622\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">return null;\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u0627\u06cc\u06a9 \u06c1\u06cc \u063a\u0644\u0637 \u0627\u0646 \u067e\u0679 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0628\u06c1\u062a \u0645\u062e\u062a\u0644\u0641 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u0628\u0631\u062a\u0627\u0624 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u06cc\u0631\u0627\u062b\u06cc \u0648\u0631\u0698\u0646 \u0648\u0627\u0636\u062d \u0637\u0648\u0631 \u067e\u0631 \u0646\u0627\u06a9\u0627\u0645 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u060c \u0644\u06cc\u06a9\u0646 \u0646\u06cc\u0627 \u0648\u0631\u0698\u0646 \u062e\u0648\u062f \u0628\u062e\u0648\u062f \u0627\u06cc\u06a9 \u0642\u062f\u0631 \u0644\u0648\u0679\u0627\u062a\u0627 \u06c1\u06d2 \u062c\u0633\u06d2 \u06a9\u0627\u0644\u0631 \u06a9\u0627\u0645\u06cc\u0627\u0628 \u0646\u062a\u06cc\u062c\u06c1 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u0628\u06cc\u0627\u0646 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u0635\u0631\u0641 \u0627\u06cc\u0633\u06d2 \u0645\u0639\u0627\u0645\u0644\u0627\u062a \u0645\u06cc\u06ba \u0686\u0644\u062a\u06cc \u06c1\u06d2 \u062c\u06c1\u0627\u06ba \u062f\u0631\u0633\u062a \u06af\u0627\u06c1\u06a9 \u0645\u0648\u062c\u0648\u062f \u06c1\u06cc\u06ba\u060c \u062a\u0648 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u062f\u06a9\u06be\u0627\u0626\u06cc \u062f\u06d2 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u06cc\u06c1 \u0645\u0639\u0627\u06c1\u062f\u06c1 \u062a\u0628\u062f\u06cc\u0644\u06cc \u067e\u0648\u0634\u06cc\u062f\u06c1 \u0631\u06c1\u06d2 \u06af\u06cc\u06d4<\/p>\n<p>\u0627\u0633 \u0644\u06cc\u06d2 \u06c1\u0645\u06cc\u06ba \u0646\u0627\u06a9\u0627\u0645\u06cc \u06a9\u06d2 \u0631\u0648\u06cc\u06d2 \u06a9\u0627 \u0628\u06be\u06cc \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2\u06d4<\/p>\n<p>\u063a\u0644\u0637\u06cc\u0648\u06ba \u06a9\u0648 \u067e\u06a9\u0691\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u06a9\u06cc\u0633 \u0628\u0646\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-typescript\">async function captureResult<t>(\n  operation: () => Promise<t>\n) {\n  try {\n    return {\n      type: \"success\" as const,\n      value: await operation(),\n    };\n  } catch (error) {\n    return {\n      type: \"error\" as const,\n      error:\n        error instanceof Error\n          ? error.message\n          : String(error),\n    };\n  }\n}\n<\/t><\/t><\/code><\/pre>\n<p>\u0627\u06cc\u06a9 \u0645\u062f\u062f\u06af\u0627\u0631 \u0627\u06cc\u06a9 \u063a\u06cc\u0631 \u0645\u0637\u0627\u0628\u0642\u062a \u067e\u0630\u06cc\u0631 \u0622\u067e\u0631\u06cc\u0634\u0646 \u06a9\u0648 \u0644\u067e\u06cc\u0679\u062a\u0627 \u06c1\u06d2 \u0627\u0648\u0631 \u062a\u0645\u0627\u0645 \u0645\u0645\u06a9\u0646\u06c1 \u0646\u062a\u0627\u0626\u062c \u06a9\u0648 \u0688\u06cc\u0679\u0627 \u0645\u06cc\u06ba \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u0622\u067e\u0631\u06cc\u0634\u0646 \u06a9\u0627\u0645\u06cc\u0627\u0628 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u060c \u062a\u0648 \u06cc\u06c1 \u0627\u0633 \u0637\u0631\u062d \u06a9\u06cc \u0686\u06cc\u0632 \u0644\u0648\u0679\u0627\u062a\u0627 \u06c1\u06d2: <code>type: \"success\"<\/code> \u0627\u0648\u0631 \u0644\u0648\u0679\u06cc \u06c1\u0648\u0626\u06cc \u0642\u06cc\u0645\u062a\u06d4 \u062c\u0628 \u06a9\u0627\u0645 \u0631\u06a9 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4 <code>catch<\/code> \u0628\u0644\u0627\u06a9 \u0627\u0633 \u0627\u0633\u062a\u062b\u0646\u0627 \u06a9\u0648 \u0627\u0633 \u0637\u0631\u062d \u06a9\u06cc \u0686\u06cc\u0632 \u0645\u06cc\u06ba \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2: <code>type: \"error\"<\/code> \u0627\u0648\u0631 \u067e\u0691\u06be\u0646\u06d2 \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u063a\u0644\u0637\u06cc \u06a9\u0627 \u067e\u06cc\u063a\u0627\u0645\u06d4<\/p>\n<p>\u06cc\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0639\u0645\u0644\u0648\u06ba \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06cc \u0627\u06cc\u06a9 \u06c1\u06cc \u0634\u06a9\u0644 \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u060c \u0679\u06cc\u0633\u0679\u0648\u06ba \u06a9\u0648 \u06a9\u0627\u0645\u06cc\u0627\u0628\u06cc \u0627\u0648\u0631 \u0646\u0627\u06a9\u0627\u0645\u06cc \u06a9\u0627 \u0648\u0627\u0636\u062d \u0637\u0648\u0631 \u067e\u0631 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0627\u062c\u0627\u0632\u062a \u062f\u06cc\u062a\u0627 \u06c1\u06d2\u060c \u0628\u062c\u0627\u0626\u06d2 \u0627\u0633 \u06a9\u06d2 \u06a9\u06c1 \u062f\u0648\u0646\u0648\u06ba \u06a9\u0627\u0631\u0631\u0648\u0627\u0626\u06cc\u0648\u06ba \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06a9\u0633\u06cc \u0627\u0633\u062a\u062b\u0646\u0627 \u06a9\u06cc \u0648\u062c\u06c1 \u0633\u06d2 \u0679\u06cc\u0633\u0679 \u06a9\u0648 \u0631\u0648\u06a9\u0627 \u062c\u0627\u0626\u06d2\u06d4<\/p>\n<p>\u0627\u0628:<\/p>\n<pre><code class=\"language-typescript\">const legacy =\n  await captureResult(() =>\n    legacyProcessor.process(input)\n  );\n\nconst migrated =\n  await captureResult(() =>\n    newProcessor.process(input)\n  );\n\nexpect(migrated.type).toBe(legacy.type);\n<\/code><\/pre>\n<p>\u0627\u06af\u0631 \u063a\u0644\u0637\u06cc \u0645\u0639\u0627\u06c1\u062f\u06c1 \u06a9\u06d2 \u0644\u062d\u0627\u0638 \u0633\u06d2 \u0645\u0627\u062f\u06cc \u06c1\u06d2 \u062a\u0648 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">error category\nHTTP status\nerror code\nretryability\nvalidation details\n<\/code><\/pre>\n<p>\u062f\u0631\u0633\u062a \u0646\u0645\u0627\u0626\u0646\u062f\u06af\u06cc\u0648\u06ba \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u0627 \u0636\u0631\u0648\u0631\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u062c\u0628 \u062a\u06a9 \u06a9\u06c1 \u0635\u0627\u0631\u0641 \u0627\u0633 \u067e\u0631 \u0627\u0646\u062d\u0635\u0627\u0631 \u0646\u06c1 \u06a9\u0631\u06d2\u06d4<\/p>\n<h2 id=\"heading-compare-side-effects-too\">\u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u0627 \u0628\u06be\u06cc \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u0646\u0642\u0644 \u0645\u06a9\u0627\u0646\u06cc \u06a9\u06cc \u0633\u0628 \u0633\u06d2 \u0622\u0633\u0627\u0646 \u063a\u0644\u0637\u06cc\u0648\u06ba \u0645\u06cc\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u0648 \u06a9\u06be\u0648\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0648\u0627\u067e\u0633\u06cc \u06a9\u06cc \u0627\u0642\u062f\u0627\u0631 \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u0631\u06a9\u06be\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u06a9\u06cc \u0648\u0627\u067e\u0633\u06cc:<\/p>\n<pre><code class=\"language-json\">{\n  \"status\": \"PROCESSED\"\n}\n<\/code><\/pre>\n<p>\u0644\u06cc\u06a9\u0646 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0648\u0631\u0698\u0646 \u0628\u06be\u06cc \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">persists the order\npublishes an event\ncreates a payment\nwrites an audit entry\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0648\u0631\u0698\u0646 \u0622\u0688\u0679 \u0627\u0646\u062f\u0631\u0627\u062c\u0627\u062a \u06a9\u0648 \u0628\u06be\u0648\u0644 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u0631\u0633\u067e\u0627\u0646\u0633 \u0644\u06cc\u0648\u0644 \u0679\u06cc\u0633\u0679\u0646\u06af \u0627\u0633 \u067e\u0631 \u06af\u0631\u0641\u062a \u0646\u06c1\u06cc\u06ba \u06a9\u0631 \u0633\u06a9\u062a\u06cc\u06d4 \u0644\u06c1\u0630\u0627 \u0622\u067e \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u067e\u0631 \u0642\u0628\u0636\u06c1 \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06ba \u06af\u06d2\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-typescript\">type Effect =\n  | {\n      type: \"payment\";\n      orderId: string;\n      amount: number;\n    }\n  | {\n      type: \"event\";\n      name: string;\n      orderId: string;\n    };\n<\/code><\/pre>\n<p>\u0679\u06cc\u0633\u0679 \u0627\u0688\u0627\u067e\u0679\u0631 \u0627\u0633\u06d2 \u0644\u0627\u06af \u0627\u0646 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-typescript\">class RecordingPaymentGateway {\n  effects: Effect[] = [];\n\n  async charge(\n    orderId: string,\n    amount: number\n  ) {\n    this.effects.push({\n      type: \"payment\",\n      orderId,\n      amount,\n    });\n  }\n}\n<\/code><\/pre>\n<p>\u0627\u0635\u0644 \u0627\u062f\u0627\u0626\u06cc\u06af\u06cc \u06a9\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0628\u06be\u06cc\u062c\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2\u060c \u06cc\u06c1 \u0627\u0688\u0627\u067e\u0679\u0631 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0646\u06d2 \u06a9\u06cc\u0627 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u06a9\u0648\u0634\u0634 \u06a9\u06cc\u06d4 <code>effects<\/code> \u0635\u0641<\/p>\n<p>\u0627\u0633\u06cc \u062e\u06cc\u0627\u0644 \u06a9\u0648 \u0627\u06cc\u0648\u0646\u0679 \u067e\u0648\u0633\u0679\u0646\u06af \u067e\u0631 \u0644\u0627\u06af\u0648 \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-typescript\">class RecordingEvents {\n  effects: Effect[] = [];\n\n  async publish(\n    name: string,\n    orderId: string\n  ) {\n    this.effects.push({\n      type: \"event\",\n      name,\n      orderId,\n    });\n  }\n}\n<\/code><\/pre>\n<p>\u0627\u06cc\u067e\u0644\u06cc\u06a9\u06cc\u0634\u0646 \u0627\u0628 \u0628\u06be\u06cc \u06c1\u0645\u06cc\u0634\u06c1 \u06a9\u06cc \u0637\u0631\u062d \u0627\u062f\u0627\u0626\u06cc\u06af\u06cc \u0627\u0648\u0631 \u0627\u06cc\u0648\u0646\u0679 \u06a9\u06d2 \u0627\u0646\u062d\u0635\u0627\u0631 \u06a9\u0648 \u06a9\u0627\u0644 \u06a9\u0631\u062a\u06cc \u06c1\u06d2\u06d4 \u0627\u06cc\u06a9 \u0679\u06cc\u0633\u0679 \u0688\u0628\u0644 \u06a9\u06cc\u067e\u0686\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2 \u062c\u0648 \u06a9\u0633\u06cc \u0628\u06be\u06cc \u062d\u0642\u06cc\u0642\u06cc \u0628\u06cc\u0631\u0648\u0646\u06cc \u06a9\u0627\u0645 \u06a9\u0648 \u0627\u0646\u062c\u0627\u0645 \u062f\u06cc\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2 \u0633\u0679\u0631\u06a9\u0686\u0631\u0688 \u0688\u06cc\u0679\u0627 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631 \u06a9\u0627\u0644 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0622\u067e \u06a9\u06d2 \u0627\u067e\u0646\u06d2 \u0631\u06cc\u06a9\u0627\u0631\u0688\u0646\u06af \u0627\u0688\u0627\u067e\u0679\u0631 \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0645\u06cc\u0631\u0627\u062b \u0627\u0648\u0631 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0686\u0644\u0627\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f\u060c \u0622\u067e \u062f\u0648 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u0634\u062f\u06c1 \u0627\u062b\u0631\u0627\u062a \u06a9\u06cc \u0641\u06c1\u0631\u0633\u062a\u0648\u06ba \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u06cc\u06c1 \u062a\u0639\u06cc\u0646 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1 \u0622\u06cc\u0627 \u062f\u0648\u0646\u0648\u06ba \u0633\u0633\u0679\u0645\u0632 \u0646\u06d2 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u06cc \u06a9\u0648\u0634\u0634 \u06a9\u06cc\u06d4<\/p>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u0627\u0628 \u06c1\u0645\u06cc\u06ba \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0627\u062c\u0627\u0632\u062a \u062f\u06cc\u062a\u06cc \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">expect(newEffects).toEqual(legacyEffects);\n<\/code><\/pre>\n<p>\u0627\u06cc\u06a9 \u0628\u0627\u0631 \u067e\u06be\u0631\u060c \u062f\u0631\u0633\u062a \u062a\u0631\u062a\u06cc\u0628 \u0635\u0631\u0641 \u0627\u0633 \u0635\u0648\u0631\u062a \u0645\u06cc\u06ba \u0636\u0631\u0648\u0631\u06cc \u06c1\u06d2 \u062c\u0628 \u062d\u06a9\u0645 \u062f\u06cc\u0646\u0627 \u0636\u0631\u0648\u0631\u06cc \u06c1\u0648\u06d4<\/p>\n<h2 id=\"heading-use-tolerances-when-exact-equality-is-wrong\">\u0635\u062d\u06cc\u062d \u0645\u0633\u0627\u0648\u0627\u062a \u063a\u0644\u0637 \u06c1\u0648\u0646\u06d2 \u067e\u0631 \u0631\u0648\u0627\u062f\u0627\u0631\u06cc \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u06a9\u0686\u06be \u0688\u0648\u0645\u06cc\u0646\u0632 \u06a9\u0648 \u0642\u0637\u0639\u06cc \u0645\u0633\u0627\u0648\u06cc \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2\u06d4<\/p>\n<p>\u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u06c1\u062c\u0631\u062a \u0634\u062f\u06c1 \u062d\u0633\u0627\u0628 \u06a9\u062a\u0627\u0628 \u067e\u06cc\u062f\u0627 \u06a9\u0631\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">legacy \u2192 34.333333333\nnew    \u2192 34.333333334\n<\/code><\/pre>\n<p>\u06a9\u06cc\u0627 \u06cc\u06c1 \u06c1\u062c\u0631\u062a \u06a9\u0627 \u0628\u06af \u06c1\u06d2\u061f \u0634\u0627\u06cc\u062f \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0641\u0644\u0648\u0679\u0646\u06af \u067e\u0648\u0627\u0626\u0646\u0679 \u06a9\u06cc\u0644\u06a9\u0648\u0644\u06cc\u0634\u0646\u0632 \u0631\u0648\u0627\u062f\u0627\u0631\u06cc \u06a9\u0627 \u062c\u0648\u0627\u0632 \u067e\u06cc\u0634 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-typescript\">expect(newResult).toBeCloseTo(\n  legacyResult,\n  6\n);\n<\/code><\/pre>\n<p>\u06cc\u0627 \u0627\u06cc\u06a9 \u0648\u0627\u0636\u062d \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">function withinTolerance(\n  a: number,\n  b: number,\n  tolerance: number\n) {\n  return Math.abs(a - b) <= tolerance;\n}\n<\/code><\/pre>\n<p>\u067e\u06be\u0631:<\/p>\n<pre><code class=\"language-typescript\">expect(\n  withinTolerance(\n    migrated.total,\n    legacy.total,\n    0.01\n  )\n).toBe(true);\n<\/code><\/pre>\n<p>\u062a\u0627\u06c1\u0645\u060c \u0631\u0648\u0627\u062f\u0627\u0631\u06cc \u06a9\u0648 \u0688\u0648\u0645\u06cc\u0646 \u06a9\u06cc \u0636\u0631\u0648\u0631\u06cc\u0627\u062a \u0633\u06d2 \u0622\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2\u06d4 \u0627\u0633\u06d2 \u0635\u0631\u0641 \u0646\u0627\u06a9\u0627\u0645 \u0679\u06cc\u0633\u0679\u0648\u06ba \u06a9\u0648 \u062f\u0648\u0631 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u062c\u0628 \u0645\u0627\u0644\u06cc\u0627\u062a\u06cc \u0646\u0638\u0627\u0645 \u06a9\u06cc \u0628\u0627\u062a \u0622\u062a\u06cc \u06c1\u06d2 \u062a\u0648\u060c \u06c1\u0631 \u0641\u06cc\u0635\u062f \u0627\u06c1\u0645\u06cc\u062a \u0631\u06a9\u06be\u062a\u0627 \u06c1\u06d2\u06d4 \u0633\u0627\u0626\u0646\u0633\u06cc \u062d\u0633\u0627\u0628\u0627\u062a \u06a9\u06d2 \u0644\u06cc\u06d2\u060c \u0628\u06c1\u062a \u0686\u06be\u0648\u0679\u06d2 \u0639\u062f\u062f\u06cc \u0641\u0631\u0642 \u0627\u06c1\u0645 \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u0633\u0627\u0648\u0627\u062a \u0627\u06cc\u06a9 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0627\u0648\u0631 \u0627\u0646\u062c\u06cc\u0646\u0626\u0631\u0646\u06af \u06a9\u0627 \u0641\u06cc\u0635\u0644\u06c1 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-build-a-reusable-differential-test-harness\">\u062f\u0648\u0628\u0627\u0631\u06c1 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u06c1\u0627\u0631\u0646\u0633 \u0628\u0646\u0627\u0646\u0627<\/h2>\n<p>\u06a9\u06cc\u0633\u0632 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0633\u06d2 \u0622\u067e \u06a9\u0648 \u062f\u0648\u0628\u0627\u0631\u06c1 \u0642\u0627\u0628\u0644 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06c1\u0627\u0631\u0646\u0633 \u0628\u0646\u0627\u0646\u06d2 \u0645\u06cc\u06ba \u0645\u062f\u062f \u0645\u0644 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-typescript\">type DifferentialResult<t> = {\n  input: T;\n  equivalent: boolean;\n  legacy: unknown;\n  migrated: unknown;\n};\n\nasync function compareImplementations<\n  TInput,\n  TOutput\n>(\n  input: TInput,\n  legacy: (\n    input: TInput\n  ) => Promise<toutput>,\n  migrated: (\n    input: TInput\n  ) => Promise<toutput>,\n  normalize: (\n    output: TOutput\n  ) => unknown\n): Promise<\n  DifferentialResult<tinput>\n> {\n  const legacyResult =\n    await legacy(\n      structuredClone(input)\n    );\n\n  const migratedResult =\n    await migrated(\n      structuredClone(input)\n    );\n\n  const normalizedLegacy =\n    normalize(legacyResult);\n\n  const normalizedMigrated =\n    normalize(migratedResult);\n\n  return {\n    input,\n    equivalent:\n      JSON.stringify(\n        normalizedLegacy\n      ) ===\n      JSON.stringify(\n        normalizedMigrated\n      ),\n    legacy: normalizedLegacy,\n    migrated: normalizedMigrated,\n  };\n}\n<\/tinput><\/toutput><\/toutput><\/t><\/code><\/pre>\n<p>\u06c1\u0627\u0631\u0646\u0633 \u0686\u0627\u0631 \u06a9\u0627\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2:<\/p>\n<p>\u0633\u0628 \u0633\u06d2 \u067e\u06c1\u0644\u06d2\u060c \u0686\u0648\u0646\u06a9\u06c1 \u06c1\u0645 \u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u06cc \u0627\u0644\u06af \u0627\u0644\u06af \u0646\u0642\u0644\u0648\u06ba \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u062a\u06d2 \u06c1\u0648\u0626\u06d2 \u0645\u06cc\u0631\u0627\u062b \u0627\u0648\u0631 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0686\u0644\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u0627\u0633 \u0644\u06cc\u06d2 \u0627\u06cc\u06a9 \u0639\u0645\u0644\u062f\u0631\u0622\u0645\u062f \u0688\u06cc\u0679\u0627 \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u0646\u06c1\u06cc\u06ba \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u062c\u0648 \u062f\u0648\u0633\u0631\u06d2 \u0627\u06cc\u06af\u0632\u06cc\u06a9\u06cc\u0648\u0634\u0646 \u06a9\u0648 \u0646\u0638\u0631 \u0622\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u062f\u0648\u0633\u0631\u0627\u060c \u06c1\u0645 \u062f\u0648\u0646\u0648\u06ba \u0622\u0624\u0679 \u067e\u0679 \u06a9\u0648 \u0627\u06cc\u06a9 \u06c1\u06cc \u0631\u0627\u0633\u062a\u06d2 \u067e\u0631 \u0631\u0648\u0679 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 <code>normalize()<\/code> \u0641\u0646\u06a9\u0634\u0646 \u06cc\u06c1 \u0645\u0633\u0627\u0648\u0627\u062a \u06a9\u06d2 \u0627\u0635\u0648\u0644\u0648\u06ba \u06a9\u0648 \u06c1\u0631 \u0627\u0645\u062a\u062d\u0627\u0646 \u0645\u06cc\u06ba \u062f\u06c1\u0631\u0627\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2 \u0627\u06cc\u06a9 \u062c\u06af\u06c1 \u067e\u0631 \u0644\u0627\u06af\u0648 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u062a\u06cc\u0633\u0631\u0627\u060c \u06c1\u0645 \u0639\u0627\u0645 \u0646\u062a\u0627\u0626\u062c \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u0627\u0648\u0631 \u0646\u0648\u0679 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1 \u0622\u06cc\u0627 \u0648\u06c1 \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0622\u062e\u0631 \u0645\u06cc\u06ba\u060c \u06cc\u06c1 \u0627\u0646 \u067e\u0679 \u0627\u0648\u0631 \u0646\u0627\u0631\u0645\u0644\u0627\u0626\u0632\u0688 \u0622\u0624\u0679 \u067e\u0679 \u06a9\u0648 \u0627\u06cc\u06a9 \u0633\u0627\u062a\u06be \u0644\u0648\u0679\u0627\u062a\u0627 \u06c1\u06d2\u06d4 \u0679\u06cc\u0633\u0679 \u0631\u067e\u0648\u0631\u0679\u0633 \u0646\u0627\u06a9\u0627\u0645 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0627 \u0645\u0639\u0627\u0626\u0646\u06c1 \u06a9\u0631\u0646\u0627 \u0622\u0633\u0627\u0646 \u0628\u0646\u0627\u062a\u06cc \u06c1\u06cc\u06ba \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u0648\u06c1 \u0622\u067e \u06a9\u0648 \u0628\u0627\u0644\u06a9\u0644 \u062f\u06a9\u06be\u0627 \u0633\u06a9\u062a\u06cc \u06c1\u06cc\u06ba \u06a9\u06c1 \u06a9\u0648\u0646 \u0633\u06d2 \u0645\u0639\u0627\u0645\u0644\u0627\u062a \u0633\u0627\u0645\u0646\u06d2 \u0622\u0626\u06d2 \u0627\u0648\u0631 \u06c1\u0631 \u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u0633\u06d2 \u06a9\u06cc\u0627 \u0646\u062a\u06cc\u062c\u06c1 \u0646\u06a9\u0644\u0627\u06d4<\/p>\n<p>\u067e\u06be\u0631:<\/p>\n<pre><code class=\"language-typescript\">const result =\n  await compareImplementations(\n    input,\n    legacyProcessor.process.bind(\n      legacyProcessor\n    ),\n    newProcessor.process.bind(\n      newProcessor\n    ),\n    normalizeOrder\n  );\n\nexpect(result.equivalent).toBe(true);\n<\/code><\/pre>\n<p>\u062d\u0642\u06cc\u0642\u06cc \u0646\u0638\u0627\u0645\u0648\u06ba \u06a9\u06d2 \u0644\u06cc\u06d2\u060c \u0622\u067e \u0639\u0627\u0645 \u0637\u0648\u0631 \u067e\u0631 \u0627\u0646\u062d\u0635\u0627\u0631 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u06d2: <code>JSON.stringify()<\/code> \u0627\u06cc\u06a9 \u062d\u062a\u0645\u06cc \u0645\u0633\u0627\u0648\u0627\u062a \u06a9\u06d2 \u0637\u0631\u06cc\u0642\u06c1 \u06a9\u0627\u0631 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631\u06d4<\/p>\n<p>\u0627\u0633 \u0645\u062b\u0627\u0644 \u0645\u06cc\u06ba \u06c1\u0645 \u06c1\u0627\u0631\u0646\u0633 \u06a9\u0648 \u067e\u0691\u06be\u0646\u06d2 \u06a9\u06d2 \u0642\u0627\u0628\u0644 \u0631\u06a9\u06be\u06cc\u06ba \u06af\u06d2\u06d4<\/p>\n<p>\u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u06a9\u0648\u0627\u0644\u0679\u06cc \u0679\u0648\u0644\u0646\u06af \u0645\u06cc\u06ba\u060c \u0645\u0646\u0627\u0633\u0628 \u0633\u0627\u062e\u062a\u06cc \u06cc\u0627 \u0688\u0648\u0645\u06cc\u0646 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u062e\u0635\u0648\u0635 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0627\u0631 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06c1\u0645 \u062d\u0635\u06c1 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u0645\u0648\u0627\u0632\u0646\u06c1 \u0645\u0646\u0637\u0642 \u0645\u0631\u06a9\u0632\u06cc \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-generate-test-cases-from-real-behavior\">\u062d\u0642\u06cc\u0642\u06cc \u0631\u0648\u06cc\u06d2 \u0633\u06d2 \u0679\u06cc\u0633\u0679 \u06a9\u06cc\u0633\u0632 \u0628\u0646\u0627\u0626\u06cc\u06ba<\/h2>\n<p>\u06c1\u0627\u062a\u06be \u0633\u06d2 \u0644\u06a9\u06be\u06cc \u06c1\u0648\u0626\u06cc \u0645\u062b\u0627\u0644\u06cc\u06ba \u0645\u062f\u062f\u06af\u0627\u0631 \u06c1\u06cc\u06ba\u06d4 \u062a\u0627\u06c1\u0645\u060c \u06c1\u062c\u0631\u062a \u0627\u06a9\u062b\u0631 \u0646\u0627\u06a9\u0627\u0645 \u06c1\u0648 \u062c\u0627\u062a\u06cc \u06c1\u06d2 \u0627\u06af\u0631 \u06a9\u0648\u0626\u06cc \u0627\u0646\u06c1\u06cc\u06ba \u062f\u0633\u062a\u06cc \u0637\u0648\u0631 \u067e\u0631 \u0644\u06a9\u06be\u0646\u06d2 \u06a9\u0648 \u062a\u06cc\u0627\u0631 \u0646\u06c1 \u06c1\u0648\u06d4<\/p>\n<p>\u0645\u0641\u06cc\u062f \u0627\u0646 \u067e\u0679 \u0630\u0631\u0627\u0626\u0639 \u0645\u06cc\u06ba \u0634\u0627\u0645\u0644 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">existing test fixtures\nhistorical incidents\nproduction-safe request samples\ndatabase records\nboundary values\nprevious bug reports\nknown customer scenarios\n<\/code><\/pre>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u0622\u0631\u0688\u0631 \u0641\u0627\u0631\u0645 \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631\u062a\u06cc \u06c1\u06d2:<\/p>\n<pre><code class=\"language-typescript\">const cases: Order[] = [\n  {\n    subtotal: 0,\n    customerType: \"STANDARD\",\n    country: \"US\",\n  },\n  {\n    subtotal: 500,\n    customerType: \"PREMIUM\",\n    country: \"AR\",\n  },\n  {\n    subtotal: 10000,\n    customerType: \"STANDARD\",\n    country: \"AR\",\n  },\n];\n<\/code><\/pre>\n<p>\u067e\u06c1\u0644\u0627 \u0628\u0644\u0627\u06a9 \u0679\u06cc\u0633\u0679 \u0688\u06cc\u0679\u0627 \u06c1\u06d2\u06d4 \u06cc\u06c1 \u062d\u0642\u06cc\u0642\u06cc \u062f\u0646\u06cc\u0627 \u06a9\u06d2 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u0645\u06cc\u06ba \u0645\u0634\u0627\u06c1\u062f\u06c1 \u06a9\u0631\u062f\u06c1 \u0646\u0645\u0627\u0626\u0646\u062f\u06c1 \u0627\u0646 \u067e\u0679 \u0634\u06a9\u0644\u0648\u06ba \u06a9\u06d2 \u0627\u06cc\u06a9 \u0686\u06be\u0648\u0679\u06d2 \u0633\u06d2 \u0633\u06cc\u0679 \u06a9\u0648 \u067e\u06a9\u0691\u062a\u0627 \u06c1\u06d2 \u06cc\u0627 \u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u0622\u067e\u0631\u06cc\u0634\u0646 \u0633\u06d2 \u0645\u062d\u0641\u0648\u0638 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u062f\u0648\u0628\u0627\u0631\u06c1 \u062a\u0634\u06a9\u06cc\u0644 \u062f\u06cc\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06af\u0644\u0627 \u0628\u0644\u0627\u06a9 \u062e\u0648\u062f \u0679\u06cc\u0633\u0679 \u06c1\u06d2\u06d4 <code>it.each(cases)<\/code> Vitest \u06a9\u0648 \u0627\u0633 \u0635\u0641 \u0645\u06cc\u06ba \u0645\u0648\u062c\u0648\u062f \u062a\u0645\u0627\u0645 \u0627\u0646 \u067e\u0679\u0633 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0627\u06cc\u06a9 \u06c1\u06cc \u0645\u0631\u062a\u0628\u06c1 \u0627\u06cc\u06a9 \u06c1\u06cc \u062a\u0641\u0631\u06cc\u0642 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u0686\u0644\u0627\u0646\u06d2 \u06a9\u06cc \u06c1\u062f\u0627\u06cc\u062a \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u062f\u0648 \u062e\u062f\u0634\u0627\u062a \u06a9\u0648 \u0627\u0644\u06af \u06a9\u0631\u062a\u0627 \u06c1\u06d2: \u062d\u0642\u06cc\u0642\u062a \u067e\u0633\u0646\u062f\u0627\u0646\u06c1 \u06a9\u06cc\u0633\u0632 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u0646\u0627 \u0627\u0648\u0631 \u062a\u0645\u0627\u0645 \u06a9\u06cc\u0633\u0632 \u06a9\u0627 \u062c\u0627\u0626\u0632\u06c1 \u0644\u06cc\u0646\u06d2 \u06a9\u06d2 \u0637\u0631\u06cc\u0642\u06d2 \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u0646\u0627\u06d4<\/p>\n<p>\u0627\u0628:<\/p>\n<pre><code class=\"language-typescript\">it.each(cases)(\n  \"matches legacy behavior\",\n  async (input) => {\n    const legacy =\n      await legacyProcessor.process(\n        structuredClone(input)\n      );\n\n    const migrated =\n      await newProcessor.process(\n        structuredClone(input)\n      );\n\n    expect(\n      normalizeOrder(migrated)\n    ).toEqual(\n      normalizeOrder(legacy)\n    );\n  }\n);\n<\/code><\/pre>\n<p>\u062d\u0642\u06cc\u0642\u06cc \u062f\u0646\u06cc\u0627 \u06a9\u06cc \u0645\u062b\u0627\u0644\u06cc\u06ba \u0627\u0646 \u0645\u0641\u0631\u0648\u0636\u0648\u06ba \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631\u0646\u06d2 \u0645\u06cc\u06ba \u0645\u062f\u062f \u06a9\u0631\u062a\u06cc \u06c1\u06cc\u06ba \u062c\u0648 \u0645\u0635\u0646\u0648\u0639\u06cc \u0679\u06cc\u0633\u0679 \u06a9\u06d2 \u0627\u0639\u062f\u0627\u062f \u0648 \u0634\u0645\u0627\u0631 \u0627\u06a9\u062b\u0631 \u0686\u06be\u0648\u0679 \u062c\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u062a\u0627\u06c1\u0645\u060c \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u06a9\u06d2 \u0627\u0639\u062f\u0627\u062f \u0648 \u0634\u0645\u0627\u0631 \u06a9\u0648 \u0627\u062d\u062a\u06cc\u0627\u0637 \u0633\u06d2 \u06c1\u06cc\u0646\u0688\u0644 \u06a9\u06cc\u0627 \u062c\u0627\u0646\u0627 \u0686\u0627\u06c1\u0626\u06d2.<\/p>\n<p>\u06c1\u0679\u0627\u0646\u0627 \u06cc\u0627 \u06af\u0645\u0646\u0627\u0645\u06cc:<\/p>\n<pre><code class=\"language-text\">personal data\ncredentials\ntokens\nfinancial identifiers\nconfidential business data\n<\/code><\/pre>\n<p>\u0645\u0642\u0635\u062f \u062d\u0633\u0627\u0633 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631\u06cc \u0645\u0639\u0644\u0648\u0645\u0627\u062a \u06a9\u0648 \u0679\u06cc\u0633\u0679 \u06a9\u06cc \u0633\u06c1\u0648\u0644\u062a \u0645\u06cc\u06ba \u06a9\u0627\u067e\u06cc \u06a9\u0631\u0646\u0627 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u060c \u0628\u0644\u06a9\u06c1 \u0645\u0641\u06cc\u062f \u0631\u0648\u06cc\u06d2 \u06a9\u06d2 \u0646\u0645\u0648\u0646\u0648\u06ba \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u06a9\u0631\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-classify-every-difference\">\u062a\u0645\u0627\u0645 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u0648 \u062d\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u063a\u0644\u0637\u06cc \u06a9\u0627 \u062e\u0648\u062f \u0628\u062e\u0648\u062f \u06cc\u06c1 \u0645\u0637\u0644\u0628 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u0646\u06cc\u0627 \u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u062e\u0631\u0627\u0628 \u06c1\u06d2\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u0648 200 \u062a\u0636\u0627\u062f\u0627\u062a \u0645\u0644\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0627\u0633\u06d2 \u062a\u0631\u062a\u06cc\u0628 \u062f\u06cc\u06ba\u06d4<\/p>\n<p>\u0645\u062c\u06be\u06d2 \u062f\u0631\u062c \u0630\u06cc\u0644 \u0632\u0645\u0631\u06d2 \u067e\u0633\u0646\u062f \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">migration defect\nlegacy defect intentionally preserved\nintentional behavior change\nrepresentation difference\nnondeterministic difference\ntest\/comparator defect\nunknown\n<\/code><\/pre>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">Input:\nsubtotal = 5000\n\nLegacy:\ndiscount = 0\n\nNew:\ndiscount = 500\n\nClassification:\nunknown\n<\/code><\/pre>\n<p>\u06c1\u0645\u0627\u0631\u06cc \u062a\u062d\u0642\u06cc\u0642\u0627\u062a \u0633\u06d2 \u067e\u062a\u06c1 \u0686\u0644\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0646\u0626\u06d2 \u0646\u0641\u0627\u0630 \u0645\u06cc\u06ba \u062f\u0631\u062c \u0630\u06cc\u0644 \u062a\u0628\u062f\u06cc\u0644\u06cc\u0627\u06ba \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-typescript\">amount > 5000\n<\/code><\/pre>\n<p>\u06a9\u0648:<\/p>\n<pre><code class=\"language-typescript\">amount >= 5000\n<\/code><\/pre>\n<p>\u0627\u0628 \u0627\u06cc\u06a9 \u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u0646\u062f\u0631\u062c\u0627\u062a \u062f\u0631\u062c \u0630\u06cc\u0644 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">accidental migration change\n<\/code><\/pre>\n<p>\u06cc\u0627:<\/p>\n<pre><code class=\"language-text\">intentional bug fix\n<\/code><\/pre>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u0641\u06cc\u0635\u0644\u0648\u06ba \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631\u062a\u06cc \u06c1\u06d2\u06d4 \u06cc\u06c1 \u0622\u067e \u06a9\u06d2 \u0644\u06cc\u06d2 \u0641\u06cc\u0635\u0644\u06d2 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u0633\u0628 \u0633\u06d2 \u0628\u0691\u06d2 \u0641\u0627\u0626\u062f\u06d2 \u0645\u06cc\u06ba \u0633\u06d2 \u0627\u06cc\u06a9 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-how-to-use-ai-to-investigate-differential-failures\">\u0645\u062e\u062a\u0644\u0641 \u063a\u0644\u0637\u06cc\u0648\u06ba \u06a9\u06cc \u062a\u062d\u0642\u06cc\u0642\u0627\u062a \u06a9\u06d2 \u0644\u06cc\u06d2 AI \u06a9\u0627 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc\u0633\u06d2 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u0628\u0691\u06d2 \u067e\u06cc\u0645\u0627\u0646\u06d2 \u067e\u0631 \u0646\u0642\u0644 \u0645\u06a9\u0627\u0646\u06cc \u06a9\u06d2 \u0646\u062a\u06cc\u062c\u06d2 \u0645\u06cc\u06ba \u0633\u06cc\u0646\u06a9\u0691\u0648\u06ba \u06cc\u0627 \u0627\u0633 \u0633\u06d2 \u0628\u06be\u06cc \u06c1\u0632\u0627\u0631\u0648\u06ba \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 AI \u0627\u0633 \u06a9\u0648 \u062d\u0644 \u06a9\u0631\u0646\u06d2 \u0645\u06cc\u06ba \u0645\u062f\u062f \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u06cc \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u0635\u0648\u0631\u062a \u062d\u0627\u0644 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-json\">{\n  \"input\": {\n    \"subtotal\": 5000,\n    \"country\": \"AR\"\n  },\n  \"legacy\": {\n    \"total\": 4500\n  },\n  \"new\": {\n    \"total\": 4000\n  }\n}\n<\/code><\/pre>\n<p>\u0622\u067e \u0627\u067e\u0646\u0627 \u0645\u0627\u0688\u0644 \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<ul>\n<li>\n<p>\u0627\u0646 \u067e\u0679<\/p>\n<\/li>\n<li>\n<p>\u062f\u0648\u0646\u0648\u06ba \u0622\u0624\u0679 \u067e\u0679<\/p>\n<\/li>\n<li>\n<p>\u0645\u062a\u0639\u0644\u0642\u06c1 \u0645\u06cc\u0631\u0627\u062b\u06cc \u06a9\u0648\u0688<\/p>\n<\/li>\n<li>\n<p>\u0645\u062a\u0639\u0644\u0642\u06c1 \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u0648\u0688<\/p>\n<\/li>\n<li>\n<p>\u062a\u0642\u0627\u0628\u0644\u06cc \u0642\u0648\u0627\u0639\u062f<\/p>\n<\/li>\n<\/ul>\n<p>\u067e\u06be\u0631 \u0633\u0648\u0627\u0644 \u067e\u0648\u0686\u06be\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-text\">Analyze this differential test failure.\n\nIdentify the smallest behavioral difference that could\nexplain the mismatch.\n\nCompare the legacy and migrated implementations.\n\nReturn:\n\n1. observed difference,\n2. relevant legacy branch,\n3. relevant migrated branch,\n4. likely cause,\n5. evidence supporting the cause,\n6. additional test cases that could confirm it.\n\nDo not decide which behavior is correct.\nDo not modify the code yet.\n<\/code><\/pre>\n<p>\u0622\u062e\u0631\u06cc \u06c1\u062f\u0627\u06cc\u062a \u0627\u06c1\u0645 \u06c1\u06d2\u06d4 AI \u06cc\u06c1 \u062c\u0627\u0646\u0646\u06d2 \u0645\u06cc\u06ba \u0628\u06c1\u062a \u0645\u0641\u06cc\u062f \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u062f\u0648 \u0646\u0641\u0627\u0630 \u0645\u062e\u062a\u0644\u0641 \u06a9\u06cc\u0648\u06ba \u06c1\u06cc\u06ba\u06d4 \u0627\u0633 \u062a\u0634\u062e\u06cc\u0635 \u06a9\u0648 \u062e\u0627\u0645\u0648\u0634\u06cc \u0633\u06d2 \u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0641\u06cc\u0635\u0644\u06d2 \u0645\u06cc\u06ba \u062a\u0631\u062c\u0645\u06c1 \u0646\u06c1\u06cc\u06ba \u06a9\u06cc\u0627 \u062c\u0627\u0646\u0627 \u0686\u0627\u06c1\u0626\u06d2\u06d4<\/p>\n<h3 id=\"heading-dont-let-ai-decide-which-behavior-is-correct\">AI \u06a9\u0648 \u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631\u0646\u06d2 \u0646\u06c1 \u062f\u06cc\u06ba \u06a9\u06c1 \u06a9\u0648\u0646 \u0633\u0627 \u0639\u0645\u0644 \u062f\u0631\u0633\u062a \u06c1\u06d2\u06d4<\/h3>\n<p>\u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u0622\u067e \u06a9\u0627 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u06a9\u0627\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">Customer age 65 \u2192 no discount\nCustomer age 66 \u2192 discount\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0646\u0638\u0627\u0645 \u06cc\u06c1 \u06a9\u0631\u06d2 \u06af\u0627:<\/p>\n<pre><code class=\"language-text\">Customer age 65 \u2192 discount\nCustomer age 66 \u2192 discount\n<\/code><\/pre>\n<p>AI \u0622\u067e \u06a9\u06d2 \u06a9\u0648\u0688 \u06a9\u0648 \u062f\u06cc\u06a9\u06be \u06a9\u0631 \u06a9\u06c1\u06c1 \u0633\u06a9\u062a\u0627 \u06c1\u06d2:<\/p>\n<blockquote>\n<p>\u0686\u0648\u0646\u06a9\u06c1 \u0633\u06cc\u0646\u0626\u0631 \u0631\u0639\u0627\u06cc\u062a\u06cc\u06ba \u0639\u0627\u0645 \u0637\u0648\u0631 \u067e\u0631 65 \u0633\u0627\u0644 \u06a9\u06cc \u0639\u0645\u0631 \u0633\u06d2 \u0634\u0631\u0648\u0639 \u06c1\u0648\u062a\u06cc \u06c1\u06cc\u06ba\u060c \u0627\u0633 \u0644\u06cc\u06d2 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0632\u06cc\u0627\u062f\u06c1 \u0645\u0646\u0637\u0642\u06cc \u0644\u06af\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/blockquote>\n<p>\u06cc\u06c1 \u0645\u062a\u0639\u0644\u0642\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u06a9\u0627\u0631\u0648\u0628\u0627\u0631\u06cc \u0642\u0648\u0627\u0646\u06cc\u0646 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">age > 65\n<\/code><\/pre>\n<p>\u0627\u06cc\u06a9 \u0648\u062c\u06c1 \u06c1\u06d2\u06d4 \u06cc\u0627\u060c \u0645\u06cc\u0631\u0627\u062b\u06cc \u0631\u0648\u06cc\u06d2 \u0645\u06cc\u06ba \u06a9\u06cc\u0691\u06d2 \u0634\u0627\u0645\u0644 \u06c1\u0648 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u06c1\u0645\u06cc\u06ba \u062b\u0628\u0648\u062a \u0686\u0627\u06c1\u06cc\u06d2\u06d4<\/p>\n<p>\u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">requirements\nexisting tests\nproduction behavior\nbusiness owners\nhistorical tickets\ncommit history\ncontracts\n<\/code><\/pre>\n<p>AI \u062b\u0628\u0648\u062a \u062c\u0645\u0639 \u06a9\u0631\u0646\u06d2 \u0627\u0648\u0631 \u062e\u0644\u0627\u0635\u06c1 \u06a9\u0631\u0646\u06d2 \u0645\u06cc\u06ba \u0645\u062f\u062f \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4 \u0622\u067e \u06a9\u0648 \u0627\u0635\u0648\u0644 \u0646\u06c1\u06cc\u06ba \u0628\u0646\u0627\u0646\u06d2 \u0686\u0627\u06c1\u0626\u06cc\u06ba\u06d4<\/p>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u0642\u0627\u0628\u0644 \u0642\u062f\u0631 \u06c1\u06d2 \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u06cc\u06c1 \u0622\u067e \u06a9\u0648 \u06cc\u06c1 \u0628\u062a\u0627\u0646\u06d2 \u062f\u06cc\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0627\u0633 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06a9\u06c1 \u0622\u067e \u063a\u0644\u0637\u06cc \u0633\u06d2 \u0627\u0633 \u0641\u0631\u0642 \u06a9\u0648 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631\u06cc \u0631\u0648\u06cc\u06d2 \u0645\u06cc\u06ba \u062a\u0631\u062c\u0645\u06c1 \u06a9\u0631 \u062f\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-how-to-use-shadow-traffic-safely\">\u0634\u06cc\u0688\u0648 \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u0646\u06d2 \u06a9\u0627 \u0637\u0631\u06cc\u0642\u06c1<\/h2>\n<p>\u062c\u06cc\u0633\u0627 \u06a9\u06c1 \u0622\u067e \u06a9\u06d2 \u0622\u0641 \u0644\u0627\u0626\u0646 \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u06a9\u06d2 \u0646\u062a\u0627\u0626\u062c \u0628\u06c1\u062a\u0631 \u06c1\u0648\u062a\u06d2 \u062c\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u0622\u067e \u0628\u0639\u0636 \u0627\u0648\u0642\u0627\u062a \u062d\u0642\u06cc\u0642\u06cc \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u0631\u0648\u06cc\u06d2 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0627\u0633\u06d2 \u0627\u06a9\u062b\u0631 \u0634\u06cc\u0688\u0648\u0646\u06af \u06cc\u0627 \u0679\u0631\u06cc\u0641\u06a9 \u0645\u0631\u0631\u0646\u06af \u06a9\u06c1\u0627 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u067e\u06cc\u0679\u0631\u0646 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">real request\n    \u2502\n    \u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 legacy system\n    \u2502                  \u2502\n    \u2502                  \u2193\n    \u2502             real response\n    \u2502\n    \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2192 new system\n                       \u2502\n                       \u2193\n                  shadow result\n<\/code><\/pre>\n<p>\u0635\u0627\u0631\u0641\u06cc\u0646 \u0648\u0635\u0648\u0644 \u06a9\u0631\u062a\u06d2 \u0631\u06c1\u06cc\u06ba \u06af\u06d2:<\/p>\n<pre><code class=\"language-text\">legacy response\n<\/code><\/pre>\n<p>\u062c\u0628 \u06a9\u06c1 \u0646\u06cc\u0627 \u0646\u0638\u0627\u0645 \u0622\u067e \u06a9\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u06cc \u0627\u06cc\u06a9 \u06a9\u0627\u067e\u06cc \u067e\u0631 \u06a9\u0627\u0631\u0631\u0648\u0627\u0626\u06cc \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u067e\u06be\u0631 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">legacy output\nvs.\nshadow output\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u0627\u06cc\u0633\u06d2 \u0645\u0639\u0627\u0645\u0644\u0627\u062a \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2 \u062c\u0646\u06c1\u06cc\u06ba \u0679\u06cc\u0633\u0679 \u0633\u0648\u06cc\u0679 \u067e\u06a9\u0691\u0646\u06d2 \u0645\u06cc\u06ba \u0646\u0627\u06a9\u0627\u0645 \u0631\u06c1\u0627\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">unexpected null combinations\nrare customer states\nunusual international data\nold records\nlarge values\nunusual sequence patterns\n<\/code><\/pre>\n<p>\u062a\u0627\u06c1\u0645\u060c \u0634\u06cc\u0688\u0648 \u067e\u0631 \u0639\u0645\u0644\u062f\u0631\u0622\u0645\u062f \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u062d\u062a\u0627\u0637 \u0688\u06cc\u0632\u0627\u0626\u0646 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u0648\u062a\u06cc \u06c1\u06d2\u060c \u062e\u0627\u0635 \u0637\u0648\u0631 \u067e\u0631 \u0627\u06af\u0631 \u0622\u067e\u0631\u06cc\u0634\u0646 \u06a9\u06d2 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06c1\u0648\u06ba\u06d4<\/p>\n<h3 id=\"heading-how-to-prevent-shadow-execution-from-duplicating-side-effects\">\u0634\u06cc\u0688\u0648 \u0627\u06cc\u06af\u0632\u06cc\u06a9\u06cc\u0648\u0634\u0646 \u06a9\u06d2 \u0646\u0642\u0644\u06cc \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u0633\u06d2 \u06a9\u06cc\u0633\u06d2 \u0628\u0686\u06cc\u06ba\u06d4<\/h3>\n<p>\u0633\u0627\u0626\u06d2 \u06a9\u0627 \u062a\u0635\u0648\u0631 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">POST \/payments\n<\/code><\/pre>\n<p>\u0627\u06af\u0631 \u0648\u06c1 \u0648\u0627\u0642\u0639\u06cc \u0627\u062f\u0627\u0626\u06cc\u06af\u06cc \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba \u062a\u0648 \u062f\u0648\u0646\u0648\u06ba \u0646\u0638\u0627\u0645\u0648\u06ba \u0645\u06cc\u06ba \u0633\u0646\u06af\u06cc\u0646 \u0645\u0633\u0627\u0626\u0644 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u0633\u06cc \u06a9\u0627 \u0627\u0637\u0644\u0627\u0642 \u0645\u0646\u062f\u0631\u062c\u06c1 \u0630\u06cc\u0644 \u067e\u0631 \u06c1\u0648\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">send email\ncreate shipment\ncharge card\nmodify inventory\npublish event\nwrite external record\n<\/code><\/pre>\n<p>\u0634\u06cc\u0688\u0648 \u06a9\u06d2 \u0646\u0641\u0627\u0630 \u06a9\u0648 \u06a9\u0648\u0626\u06cc \u062a\u0628\u0627\u06c1 \u06a9\u0646 \u06cc\u0627 \u0628\u06cc\u0631\u0648\u0646\u06cc \u0637\u0648\u0631 \u067e\u0631 \u0646\u0638\u0631 \u0622\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u0627\u062b\u0631\u0627\u062a \u06a9\u0648 \u0627\u0646\u062c\u0627\u0645 \u0646\u06c1\u06cc\u06ba \u062f\u06cc\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2 \u062c\u0628 \u062a\u06a9 \u06a9\u06c1 \u0645\u062d\u0641\u0648\u0638 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u0645\u0648\u062c\u0648\u062f \u0646\u06c1 \u06c1\u0648\u06ba\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0646\u0642\u0637\u06c1 \u0646\u0638\u0631 \u062c\u0633\u0645\u0627\u0646\u06cc \u06af\u06cc\u0679 \u0648\u06d2 \u06a9\u0648 \u0631\u06cc\u06a9\u0627\u0631\u0688\u0646\u06af \u0627\u0688\u0627\u067e\u0679\u0631 \u0633\u06d2 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-typescript\">class ShadowPaymentGateway\n  implements PaymentGateway {\n  calls: PaymentRequest[] = [];\n\n  async charge(\n    request: PaymentRequest\n  ) {\n    this.calls.push(request);\n\n    return {\n      paymentId: \"shadow\",\n    };\n  }\n}\n<\/code><\/pre>\n<p>\u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0627\u0628 \u0628\u06be\u06cc \u0686\u0644\u0627\u0646\u06d2 \u06a9\u06cc \u06a9\u0648\u0634\u0634 \u06a9\u0631\u06d2 \u06af\u0627\u06d4<\/p>\n<pre><code class=\"language-text\">payment\n<\/code><\/pre>\n<p>\u0644\u06cc\u06a9\u0646 \u0627\u0635\u0644 \u06a9\u0627\u0631\u0688 \u06a9\u0648 \u0686\u0627\u0631\u062c \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0628\u062c\u0627\u0626\u06d2\u060c \u0634\u06cc\u0688\u0648 \u0627\u0688\u0627\u067e\u0679\u0631 \u0631\u06cc\u06a9\u0627\u0631\u0688 \u06a9\u0631\u062a\u0627 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">what would have been sent\n<\/code><\/pre>\n<p>\u0627\u0633 \u06a9\u06d2 \u0628\u0639\u062f \u0622\u067e \u0627\u0633 \u0627\u0631\u0627\u062f\u06d2 \u06a9\u0627 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u0633\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u06cc\u06c1 \u0641\u0631\u0642 \u0627\u06c1\u0645 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-text\">compare behavior\n<\/code><\/pre>\n<p>\u0627\u0633 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">duplicate production effects\n<\/code><\/pre>\n<h2 id=\"heading-measure-divergence-instead-of-waiting-for-perfection\">\u06a9\u0645\u0627\u0644 \u06a9\u0627 \u0627\u0646\u062a\u0638\u0627\u0631 \u06a9\u06cc\u06d2 \u0628\u063a\u06cc\u0631 \u0627\u0646\u062d\u0631\u0627\u0641 \u06a9\u06cc \u067e\u06cc\u0645\u0627\u0626\u0634 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u062c\u0628 \u06c1\u0632\u0627\u0631\u0648\u06ba \u0645\u0648\u0627\u0632\u0646\u06c1 \u0686\u0644 \u0631\u06c1\u06d2 \u06c1\u06cc\u06ba\u060c \u0628\u0627\u0626\u0646\u0631\u06cc:<\/p>\n<pre><code class=\"language-text\">pass \/ fail\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u067e\u0648\u0631\u06cc \u06a9\u06c1\u0627\u0646\u06cc \u0646\u06c1\u06cc\u06ba \u0628\u062a\u0627 \u0633\u06a9\u062a\u0627\u06d4<\/p>\n<p>\u0627\u062e\u062a\u0644\u0627\u0641 \u06a9\u06cc \u067e\u06cc\u0645\u0627\u0626\u0634 \u06a9\u06cc \u062c\u0627 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">Requests compared:     100,000\nEquivalent:             99,620\nDifferent:                 380\n\nDivergence rate:          0.38%\n<\/code><\/pre>\n<p>\u067e\u06be\u0631 \u0627\u0646 380 \u06a9\u0648 \u062a\u0631\u062a\u06cc\u0628 \u062f\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-text\">250 timestamp differences\n80 known intentional changes\n30 comparator problems\n15 migration defects fixed\n5 still unexplained\n<\/code><\/pre>\n<p>\u0645\u0639\u0645\u0648\u0644 \u06a9\u06d2 \u0628\u0639\u062f:<\/p>\n<pre><code class=\"language-text\">meaningful unresolved divergence:\n5 \/ 100,000\n= 0.005%\n<\/code><\/pre>\n<p>\u0627\u0628 \u0628\u0627\u062a \u0686\u06cc\u062a \u0628\u06c1\u062a \u0632\u06cc\u0627\u062f\u06c1 \u0645\u062e\u0635\u0648\u0635 \u06c1\u0648 \u062c\u0627\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0628\u062c\u0627\u0626\u06d2:<\/p>\n<blockquote>\n<p>\u0627\u06cc\u0633\u0627 \u0644\u06af\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0622\u067e \u06a9\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u062a\u06cc\u0627\u0631 \u06c1\u06d2\u06d4<\/p>\n<\/blockquote>\n<p>\u0622\u067e \u06a9\u06c1\u06c1 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<blockquote>\n<p>\u06c1\u0645 \u0646\u06d2 100,000 \u0646\u0645\u0627\u0626\u0646\u062f\u06c1 \u0631\u0646\u0632 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06cc\u0627 \u0627\u0648\u0631 \u067e\u0627\u0646\u0686 \u063a\u06cc\u0631 \u062d\u0644 \u0634\u062f\u06c1 \u0637\u0631\u0632 \u0639\u0645\u0644 \u06a9\u06d2 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u067e\u0627\u0626\u06d2\u06d4<\/p>\n<\/blockquote>\n<p>\u0622\u06cc\u0627 \u06cc\u06c1 \u0642\u0627\u0628\u0644 \u0642\u0628\u0648\u0644 \u06c1\u06d2 \u0627\u0633 \u06a9\u0627 \u0627\u0646\u062d\u0635\u0627\u0631 \u067e\u0627\u0646\u0686 \u0645\u062e\u062a\u0644\u0641 \u0635\u0648\u0631\u062a\u0648\u06ba \u067e\u0631 \u06c1\u06d2:<\/p>\n<p>\u0627\u06cc\u06a9 \u062e\u0631\u0627\u0628 \u0645\u0627\u0644\u06cc \u0644\u06cc\u0646 \u062f\u06cc\u0646 \u06a9\u06d2 \u0646\u062a\u06cc\u062c\u06d2 \u0645\u06cc\u06ba 100 \u0633\u06d2 \u0632\u06cc\u0627\u062f\u06c1 \u0628\u06d2 \u0636\u0631\u0631 \u0641\u0627\u0631\u0645\u06cc\u0679 \u0645\u06cc\u06ba \u0641\u0631\u0642 \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0644\u06c1\u0630\u0627 \u0635\u0631\u0641 \u0641\u06cc\u0635\u062f \u06a9\u0627 \u0627\u0646\u062f\u0627\u0632\u06c1 \u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4 \u0634\u062f\u062a \u06a9\u0627 \u0627\u0646\u062f\u0627\u0632\u06c1 \u0644\u06af\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-how-to-know-when-youre-ready-for-cutover\">\u0627\u06af\u0631 \u0622\u067e \u06a9\u0679 \u0627\u0648\u0648\u0631 \u06a9\u06d2 \u0644\u06cc\u06d2 \u062a\u06cc\u0627\u0631 \u06c1\u06cc\u06ba \u062a\u0648 \u06a9\u06cc\u0633\u06d2 \u062c\u0627\u0646\u06cc\u06ba\u06d4<\/h2>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679\u0646\u06af \u0622\u0641\u0627\u0642\u06cc \u062d\u062f \u0641\u0631\u0627\u06c1\u0645 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u062a\u06cc \u06c1\u06d2\u06d4 \u0644\u06cc\u06a9\u0646 \u06cc\u06c1 \u062b\u0628\u0648\u062a \u062f\u06d2 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06a9\u0679 \u0627\u0648\u0648\u0631 \u0633\u06d2 \u067e\u06c1\u0644\u06d2\u060c \u0645\u06cc\u06ba \u062f\u0631\u062c \u0630\u06cc\u0644 \u0633\u0648\u0627\u0644\u0627\u062a \u06a9\u0627 \u062c\u0648\u0627\u0628 \u062f\u06cc\u0646\u0627 \u0686\u0627\u06c1\u0648\u06ba \u06af\u0627:<\/p>\n<h3 id=\"heading-have-important-input-classes-been-compared\">\u06a9\u06cc\u0627 \u0622\u067e \u0646\u06d2 \u0627\u06c1\u0645 \u0627\u0646 \u067e\u0679 \u06a9\u0644\u0627\u0633\u0632 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u06cc\u0627 \u06c1\u06d2\u061f<\/h3>\n<p>\u06cc\u06c1 \u0635\u0631\u0641 \u062e\u0648\u0634\u06cc \u06a9\u0627 \u0631\u0627\u0633\u062a\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u0634\u0627\u0645\u0644 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">boundaries\nerrors\nhistorical bugs\nlarge values\nmissing values\nrare states\n<\/code><\/pre>\n<h3 id=\"heading-are-meaningful-differences-classified\">\u06a9\u06cc\u0627 \u0645\u0639\u0646\u06cc \u062e\u06cc\u0632 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u06cc \u062f\u0631\u062c\u06c1 \u0628\u0646\u062f\u06cc \u06a9\u06cc \u06af\u0626\u06cc \u06c1\u06d2\u061f<\/h3>\n<p>\u0627\u062c\u062a\u0646\u0627\u0628:<\/p>\n<pre><code class=\"language-text\">we have 47 unexplained mismatches\n<\/code><\/pre>\n<h3 id=\"heading-are-critical-differences-resolved\">\u06a9\u06cc\u0627 \u06a9\u0648\u0626\u06cc \u0627\u06c1\u0645 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u062d\u0644 \u06c1\u0648 \u06af\u0626\u06d2 \u06c1\u06cc\u06ba\u061f<\/h3>\n<p>\u062e\u0627\u0635 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">money\nauthorization\nstate transitions\ndata integrity\nexternal contracts\nidempotency\n<\/code><\/pre>\n<h3 id=\"heading-are-intentional-differences-documented\">\u06a9\u06cc\u0627 \u06a9\u0648\u0626\u06cc \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u0648 \u062f\u0633\u062a\u0627\u0648\u06cc\u0632 \u06a9\u06cc\u0627 \u06af\u06cc\u0627 \u06c1\u06d2\u061f<\/h3>\n<p>\u0627\u06af\u0631 \u0646\u06cc\u0627 \u0631\u0648\u06cc\u06c1 \u062c\u0627\u0646 \u0628\u0648\u062c\u06be \u06a9\u0631 \u0645\u062e\u062a\u0644\u0641 \u06c1\u06d2\u060c \u062a\u0648 \u0627\u0633\u06d2 \u0628\u06cc\u0627\u0646 \u06a9\u0631\u0646\u0627 \u0636\u0631\u0648\u0631\u06cc \u06c1\u06d2\u06d4<\/p>\n<h3 id=\"heading-are-side-effects-equivalent\">\u06a9\u06cc\u0627 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u0628\u0631\u0627\u0628\u0631 \u06c1\u06cc\u06ba\u061f<\/h3>\n<p>\u06cc\u06c1 \u0635\u0631\u0641 \u0631\u062f\u0639\u0645\u0644 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<h3 id=\"heading-have-production-like-cases-been-tested\">\u06a9\u06cc\u0627 \u0622\u067e \u0646\u06d2 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631 \u0645\u06cc\u06ba \u0627\u0633\u06cc \u0637\u0631\u062d \u06a9\u06d2 \u0645\u0639\u0627\u0645\u0644\u0627\u062a \u06a9\u0627 \u062a\u062c\u0631\u0628\u06c1 \u06a9\u06cc\u0627 \u06c1\u06d2\u061f<\/h3>\n<p>\u0627\u06a9\u06cc\u0644\u06d2 \u062c\u0627\u0645\u0639 \u0641\u06a9\u0633\u0686\u0631 \u06a9\u0627\u0641\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u0648\u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-can-the-migration-be-rolled-back\">\u06a9\u06cc\u0627 \u0645\u06cc\u06ba \u06c1\u062c\u0631\u062a \u0648\u0627\u067e\u0633 \u0644\u06d2 \u0633\u06a9\u062a\u0627 \u06c1\u0648\u06ba\u061f<\/h3>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u0627\u0639\u062a\u0645\u0627\u062f \u062e\u0637\u0631\u06d2 \u06a9\u0648 \u06a9\u0645 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4 \u0627\u0633 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06cc\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u0631\u0648\u0644 \u0628\u06cc\u06a9 \u0636\u0631\u0648\u0631\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u0622\u067e \u0627\u0646 \u0633\u0648\u0627\u0644\u0648\u06ba \u06a9\u0627 \u062c\u0648\u0627\u0628 \u062f\u06d2 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u062a\u0648 \u0622\u067e \u06a9\u0646\u0679\u0631\u0648\u0644 \u0634\u062f\u06c1 \u06a9\u0679 \u0627\u0648\u0648\u0631 \u06a9\u06d2 \u0628\u06c1\u062a \u0642\u0631\u06cc\u0628 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-a-practical-differential-testing-workflow\">\u0639\u0645\u0644\u06cc \u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u0648\u0631\u06a9 \u0641\u0644\u0648<\/h2>\n<p>\u0645\u06cc\u06ba \u062c\u0648 \u0648\u0631\u06a9 \u0641\u0644\u0648 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u0648\u06ba \u06af\u0627 \u0648\u06c1 \u062f\u0631\u062c \u0630\u06cc\u0644 \u06c1\u06d2:<\/p>\n<h3 id=\"heading-1-pick-one-capability\">1. \u0627\u06cc\u06a9 \u062e\u0635\u0648\u0635\u06cc\u062a \u0645\u0646\u062a\u062e\u0628 \u06a9\u0631\u06cc\u06ba\u06d4<\/h3>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-text\">Process Order\nCalculate Invoice\nApprove Customer\n<\/code><\/pre>\n<p>\u0627\u06cc\u06a9 \u0633\u0627\u062a\u06be \u062a\u0645\u0627\u0645 \u067e\u0644\u06cc\u0679 \u0641\u0627\u0631\u0645\u0632 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-2-define-the-observable-contract\">2. \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u0645\u0639\u0627\u06c1\u062f\u06d2 \u06a9\u06cc \u062a\u0639\u0631\u06cc\u0641<\/h3>\n<p>\u0627\u06c1\u0645 \u0646\u06a9\u0627\u062a \u06a9\u06cc \u0641\u06c1\u0631\u0633\u062a \u0628\u0646\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<pre><code class=\"language-text\">return value\nstatus\nerror\ndatabase state\nevents\nexternal calls\n<\/code><\/pre>\n<h3 id=\"heading-3-create-legacy-and-new-adapters\">3. \u0645\u06cc\u0631\u0627\u062b\u06cc \u0627\u0648\u0631 \u0646\u0626\u06d2 \u0627\u0688\u0627\u067e\u0679\u0631 \u0628\u0646\u0627\u0626\u06cc\u06ba<\/h3>\n<p>\u06c1\u0645 \u0627\u06cc\u06a9 \u06c1\u06cc \u062a\u0635\u0648\u0631\u0627\u062a\u06cc \u0627\u0646\u0679\u0631\u0641\u06cc\u0633 \u06a9\u06d2 \u0630\u0631\u06cc\u0639\u06d2 \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0628\u06d2 \u0646\u0642\u0627\u0628 \u06a9\u0631\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-4-define-normalization-rules\">4. \u0645\u0639\u0645\u0648\u0644 \u06a9\u06d2 \u0627\u0635\u0648\u0644\u0648\u06ba \u06a9\u06cc \u0648\u0636\u0627\u062d\u062a \u06a9\u0631\u06cc\u06ba\u06d4<\/h3>\n<p>\u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631\u06cc\u06ba \u06a9\u06c1 \u06a9\u0633 \u0637\u0631\u062d \u0622\u06af\u06d2 \u0628\u0691\u06be\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<pre><code class=\"language-text\">timestamps\ngenerated IDs\nordering\nrepresentation changes\noptional values\n<\/code><\/pre>\n<p>\u0628\u06c1\u062a \u0632\u06cc\u0627\u062f\u06c1 \u0646\u0627\u06a9\u0627\u0645\u06cc\u0627\u06ba \u062f\u06cc\u06a9\u06be\u0646\u06d2 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u06cc\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4 \u0628\u0635\u0648\u0631\u062a \u062f\u06cc\u06af\u0631 \u0622\u067e \u0635\u0631\u0641 \u0646\u062a\u06cc\u062c\u06c1 \u067e\u0627\u0633 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u06a9\u0648 \u06a9\u0645\u0632\u0648\u0631 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-5-compare-known-cases\">5. \u0645\u0639\u0644\u0648\u0645 \u0645\u0642\u062f\u0645\u0627\u062a \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1<\/h3>\n<p>\u06a9\u06d2 \u0633\u0627\u062a\u06be \u0634\u0631\u0648\u0639 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">existing tests\ncharacterization cases\nedge cases\nhistorical bugs\n<\/code><\/pre>\n<h3 id=\"heading-6-capture-side-effects\">6. \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u0648 \u067e\u06a9\u0691\u0646\u0627<\/h3>\n<p>\u0627\u06af\u0631 \u0636\u0631\u0648\u0631\u06cc \u06c1\u0648 \u062a\u0648 \u0631\u06cc\u06a9\u0627\u0631\u0688\u0646\u06af \u06cc\u0627 \u062c\u0639\u0644\u06cc \u0627\u0688\u0627\u067e\u0679\u0631 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-7-automate-the-harness\">7. \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u0622\u0679\u0648\u0645\u06cc\u0634\u0646<\/h3>\n<p>\u062a\u0645\u0627\u0645 \u062a\u0636\u0627\u062f\u0627\u062a \u06a9\u06d2 \u0644\u06cc\u06d2 \u0633\u0679\u0631\u06a9\u0686\u0631\u0688 \u0622\u0624\u0679 \u067e\u0679 \u062a\u06cc\u0627\u0631 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0645\u062b\u0627\u0644 \u06a9\u06d2 \u0637\u0648\u0631 \u067e\u0631:<\/p>\n<pre><code class=\"language-json\">{\n  \"caseId\": \"case-493\",\n  \"equivalent\": false,\n  \"legacy\": {},\n  \"migrated\": {},\n  \"difference\": {}\n}\n<\/code><\/pre>\n<h3 id=\"heading-8-classify-differences\">8. \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u06cc \u062f\u0631\u062c\u06c1 \u0628\u0646\u062f\u06cc<\/h3>\n<p>\u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u06cc \u0642\u0633\u0645:<\/p>\n<pre><code class=\"language-text\">defect\nintentional change\nnormalization issue\nnondeterminism\nunknown\n<\/code><\/pre>\n<h3 id=\"heading-9-add-representative-real-world-cases\">9. \u0646\u0645\u0627\u0626\u0646\u062f\u06c1 \u062d\u0642\u06cc\u0642\u06cc \u0632\u0646\u062f\u06af\u06cc \u06a9\u06cc \u0645\u062b\u0627\u0644\u06cc\u06ba \u0634\u0627\u0645\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/h3>\n<p>\u06af\u0645\u0646\u0627\u0645 \u06cc\u0627 \u0645\u062d\u0641\u0648\u0638 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u062f\u0648\u0628\u0627\u0631\u06c1 \u062a\u0639\u0645\u06cc\u0631 \u0634\u062f\u06c1 \u067e\u0631\u0648\u0688\u06a9\u0634\u0646 \u067e\u06cc\u0679\u0631\u0646 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<h3 id=\"heading-10-shadow-real-traffic-when-appropriate\">10. \u062c\u06c1\u0627\u06ba \u0645\u0646\u0627\u0633\u0628 \u06c1\u0648 \u0648\u06c1\u0627\u06ba \u062d\u0642\u06cc\u0642\u06cc \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u0648 \u0634\u06cc\u0688\u0648 \u06a9\u0631\u06cc\u06ba\u06d4<\/h3>\n<p>\u06cc\u06c1 \u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u0627\u0648\u0631 \u0631\u0627\u0632\u062f\u0627\u0631\u06cc \u06a9\u06d2 \u062e\u0637\u0631\u0627\u062a \u06a9\u0648 \u06a9\u0646\u0679\u0631\u0648\u0644 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f \u06c1\u06cc \u0645\u0645\u06a9\u0646 \u06c1\u06d2\u06d4<\/p>\n<h3 id=\"heading-11-measure-divergence\">11. \u0627\u0646\u062d\u0631\u0627\u0641 \u06a9\u06cc \u067e\u06cc\u0645\u0627\u0626\u0634<\/h3>\n<p>\u062f\u0648\u0646\u0648\u06ba \u06a9\u0648 \u0679\u0631\u06cc\u06a9 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">frequency\nseverity\n<\/code><\/pre>\n<h3 id=\"heading-12-resolve-unknowns-before-cutover\">12. \u06a9\u0679 \u0627\u0648\u0648\u0631 \u0633\u06d2 \u067e\u06c1\u0644\u06d2 \u0646\u0627\u0645\u0639\u0644\u0648\u0645 \u0645\u0633\u0627\u0626\u0644 \u06a9\u0648 \u062d\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/h3>\n<p>\u0633\u0628 \u0633\u06d2 \u062e\u0637\u0631\u0646\u0627\u06a9 \u0632\u0645\u0631\u06c1 \u06cc\u06c1 \u06c1\u06d2 \u062c\u0628:<\/p>\n<pre><code class=\"language-text\">different\n<\/code><\/pre>\n<p>\u06a9\u06c1:<\/p>\n<pre><code class=\"language-text\">different and nobody knows why\n<\/code><\/pre>\n<h2 id=\"heading-what-differential-testing-cant-prove\">\u062a\u0641\u0631\u06cc\u0642 \u0679\u06cc\u0633\u0679 \u0633\u06d2 \u06a9\u06cc\u0627 \u062b\u0627\u0628\u062a \u0646\u06c1\u06cc\u06ba \u06a9\u06cc\u0627 \u062c\u0627 \u0633\u06a9\u062a\u0627<\/h2>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u06a9\u06cc \u0627\u06c1\u0645 \u062d\u062f\u0648\u062f \u06c1\u06cc\u06ba\u06d4 \u06cc\u0639\u0646\u06cc \u0646\u0626\u06d2 \u0646\u0638\u0627\u0645 \u06a9\u0627 \u067e\u0631\u0627\u0646\u06d2 \u0646\u0638\u0627\u0645 \u0633\u06d2 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u0633 \u06a9\u0627 \u0645\u0637\u0644\u0628 \u06c1\u06d2 \u06a9\u06c1 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u0631\u0648\u06cc\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0645\u0639\u06cc\u0627\u0631 \u0628\u0646 \u062c\u0627\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4 \u0644\u06cc\u06a9\u0646 \u0622\u067e \u06a9\u0627 \u0645\u06cc\u0631\u0627\u062b\u06cc \u0646\u0638\u0627\u0645 \u067e\u06c1\u0644\u06d2 \u0633\u06d2 \u06c1\u06cc \u063a\u0644\u0637 \u06c1\u0648 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0641\u0631\u0636 \u06a9\u0631\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">legacy output = wrong\nnew output    = same wrong result\n<\/code><\/pre>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u0627\u0645\u062a\u062d\u0627\u0646 \u067e\u0627\u0633 \u06c1\u0648 \u062c\u0627\u062a\u0627 \u06c1\u06d2\u060c \u0644\u06cc\u06a9\u0646 \u0631\u0648\u06cc\u06c1 \u062f\u0631\u0633\u062a \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1\u06cc \u0648\u062c\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u06a9\u0648 \u0645\u06a9\u0645\u0644 \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u0626\u06d2:<\/p>\n<pre><code class=\"language-text\">specification tests\ncharacterization tests\nbusiness requirements\nsecurity testing\nperformance testing\ncontract testing\ndomain review\n<\/code><\/pre>\n<p>\u062c\u0648\u0627\u0628 \u06cc\u06c1 \u06c1\u06d2:<\/p>\n<blockquote>\n<p>\u06a9\u06cc\u0627 \u0622\u067e \u06a9\u0627 \u0631\u0648\u06cc\u06c1 \u0628\u062f\u0644 \u06af\u06cc\u0627 \u06c1\u06d2\u061f<\/p>\n<\/blockquote>\n<p>\u06cc\u06c1 \u062e\u0648\u062f \u0628\u062e\u0648\u062f \u062c\u0648\u0627\u0628 \u0646\u06c1\u06cc\u06ba \u062f\u06cc\u062a\u0627\u06d4<\/p>\n<blockquote>\n<p>\u06a9\u06cc\u0627 \u06cc\u06c1 \u0635\u062d\u06cc\u062d \u06a9\u0627\u0645 \u06c1\u06d2\u061f<\/p>\n<\/blockquote>\n<p>\u06cc\u06c1 \u0641\u0631\u0642 \u0627\u06c1\u0645 \u06c1\u06d2\u06d4 \u0645\u06cc\u0631\u0627\u062b\u06cc \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u06cc\u06ba \u062b\u0628\u0648\u062a \u06c1\u06cc\u06ba\u060c \u0642\u0637\u0639\u06cc \u0633\u0686\u0627\u0626\u06cc \u0646\u06c1\u06cc\u06ba\u06d4<\/p>\n<h2 id=\"heading-differential-testing-turns-migration-risk-into-evidence\">\u06c1\u062c\u0631\u062a \u06a9\u06d2 \u062e\u0637\u0631\u06d2 \u06a9\u0648 \u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u062b\u0628\u0648\u062a \u0645\u06cc\u06ba \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/h2>\n<p>\u0645\u062c\u06be\u06d2 \u0627\u0633 \u0679\u06cc\u06a9\u0646\u0627\u0644\u0648\u062c\u06cc \u06a9\u0648 \u067e\u0633\u0646\u062f \u06a9\u0631\u0646\u06d2 \u06a9\u06cc \u0627\u06cc\u06a9 \u0627\u0648\u0631 \u0648\u062c\u06c1 \u06c1\u06d2\u06d4 \u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u06a9\u06d2 \u0628\u063a\u06cc\u0631\u060c \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u06d2 \u0645\u0628\u0627\u062d\u062b\u06d2 \u0645\u0648\u0636\u0648\u0639\u06cc \u0628\u0646 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0634\u062e\u0635 \u06a9\u06c1\u062a\u0627 \u06c1\u06d2:<\/p>\n<blockquote>\n<p>\u0627\u06cc\u0633\u0627 \u0644\u06af\u062a\u0627 \u06c1\u06d2 \u06a9\u06c1 \u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u062a\u06cc\u0627\u0631 \u06c1\u06d2\u06d4<\/p>\n<\/blockquote>\n<p>\u0627\u06cc\u06a9 \u0627\u0648\u0631 \u0634\u062e\u0635 \u06a9\u06c1\u062a\u0627 \u06c1\u06d2:<\/p>\n<blockquote>\n<p>\u0645\u062c\u06be\u06d2 \u0627\u0628\u06be\u06cc \u062a\u06a9 \u0627\u0633 \u067e\u0631 \u0628\u06be\u0631\u0648\u0633\u06c1 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<\/blockquote>\n<p>\u062f\u0648\u0646\u0648\u06ba \u0645\u06cc\u06ba \u0645\u0639\u0642\u0648\u0644 \u062c\u0628\u0644\u062a \u06c1\u0648 \u0633\u06a9\u062a\u06cc \u06c1\u06d2\u060c \u0644\u06cc\u06a9\u0646 \u06a9\u0648\u0626\u06cc \u0628\u06be\u06cc \u0628\u06cc\u0627\u0646 \u0642\u0627\u0628\u0644 \u067e\u06cc\u0645\u0627\u0626\u0634 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u062a\u0641\u0631\u06cc\u0642 \u06a9\u06cc \u062c\u0627\u0646\u0686 \u06af\u0641\u062a\u06af\u0648 \u06a9\u0648 \u0628\u062f\u0644 \u062f\u06cc\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u0628 \u0622\u067e \u06a9\u06c1\u06c1 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba:<\/p>\n<pre><code class=\"language-text\">12,000 cases compared\n47 differences found\n31 representation differences\n9 intentional behavior changes\n6 migration defects fixed\n1 unresolved\n<\/code><\/pre>\n<p>\u06cc\u06c1 \u0627\u06cc\u06a9 \u0628\u06c1\u062a \u0628\u06c1\u062a\u0631 \u0627\u0646\u062c\u06cc\u0646\u0626\u0631\u0646\u06af \u0628\u062d\u062b \u06c1\u06d2\u06d4 \u0622\u067e \u063a\u06cc\u0631 \u06cc\u0642\u06cc\u0646\u06cc \u06a9\u0648 \u0642\u0627\u0628\u0644 \u0645\u0634\u0627\u06c1\u062f\u06c1 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u0645\u06cc\u06ba \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631 \u0631\u06c1\u06d2 \u06c1\u06cc\u06ba\u06d4 \u067e\u06be\u0631 \u0622\u067e \u0641\u06cc\u0635\u0644\u06c1 \u06a9\u0631 \u0633\u06a9\u062a\u06d2 \u06c1\u06cc\u06ba \u06a9\u06c1 \u0627\u0646 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u06a9\u06cc\u0627 \u06a9\u0631\u0646\u0627 \u06c1\u06d2\u06d4<\/p>\n<h2 id=\"heading-conclusion\">\u0646\u062a\u06cc\u062c\u06c1<\/h2>\n<p>\u0648\u0631\u0627\u062b\u062a \u06a9\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u0645\u06a9\u0645\u0644 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06cc\u0648\u0646\u06a9\u06c1 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u06c1\u0645\u0627\u0631\u06cc \u0627\u067e\u0646\u06cc \u0622\u0632\u0645\u0627\u0626\u0634 \u0633\u06d2 \u06af\u0632\u0631 \u0686\u06a9\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u0632\u06cc\u0627\u062f\u06c1 \u0645\u0634\u06a9\u0644 \u0633\u0648\u0627\u0644 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u06a9\u06cc\u0627 \u0627\u0633 \u06a9\u06cc \u062c\u06af\u06c1 \u0644\u06cc\u0646\u06d2 \u0648\u0627\u0644\u0627 \u0646\u0638\u0627\u0645 \u0627\u06c1\u0645 \u0631\u0648\u06cc\u06d2 \u06a9\u0648 \u0645\u062d\u0641\u0648\u0638 \u0631\u06a9\u06be\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u0627\u0633 \u0633\u0648\u0627\u0644 \u06a9\u0627 \u062c\u0648\u0627\u0628 \u062f\u06cc\u0646\u06d2 \u06a9\u0627 \u0627\u06cc\u06a9 \u0627\u0648\u0631 \u0637\u0631\u06cc\u0642\u06c1 \u0641\u0631\u0627\u06c1\u0645 \u06a9\u0631\u062a\u06cc \u06c1\u06d2\u06d4<\/p>\n<p>\u0627\u06cc\u06a9 \u06c1\u06cc \u0627\u0646 \u067e\u0679 \u06a9\u06d2 \u0633\u0627\u062a\u06be \u062f\u0648\u0646\u0648\u06ba \u0646\u0641\u0627\u0630 \u06a9\u0648 \u0686\u0644\u0627\u0626\u06cc\u06ba\u06d4<\/p>\n<p>\u0622\u0624\u0679 \u067e\u0679 \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u063a\u0644\u0637\u06cc\u0648\u06ba \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0636\u0645\u0646\u06cc \u0627\u062b\u0631\u0627\u062a \u06a9\u0627 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0635\u0631\u0641 \u0627\u0646 \u0627\u062e\u062a\u0644\u0627\u0641\u0627\u062a \u06a9\u0648 \u0645\u0639\u0645\u0648\u0644 \u0628\u0646\u0627\u0626\u06cc\u06ba \u062c\u0648 \u0648\u0627\u0642\u0639\u06cc \u0627\u06c1\u0645 \u0646\u06c1\u06cc\u06ba \u06c1\u06cc\u06ba\u06d4<\/p>\n<p>\u0628\u0627\u0642\u06cc \u06c1\u0631 \u0686\u06cc\u0632 \u06a9\u06cc \u062a\u062d\u0642\u06cc\u0642 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u06af\u0631 \u0645\u0645\u06a9\u0646 \u06c1\u0648 \u062a\u0648\u060c \u0627\u067e\u0646\u06d2 \u0679\u06cc\u0633\u0679 \u0633\u0648\u06cc\u0679 \u0645\u06cc\u06ba \u063a\u06cc\u0631 \u0645\u062a\u0648\u0642\u0639 \u06a9\u06cc\u0633\u0632 \u06a9\u0648 \u067e\u06a9\u0691\u0646\u06d2 \u06a9\u06d2 \u0644\u06cc\u06d2 \u0646\u0645\u0627\u0626\u0646\u062f\u06c1 \u067e\u06cc\u062f\u0627\u0648\u0627\u0631\u06cc \u0631\u0648\u06cc\u06c1 \u0627\u0633\u062a\u0639\u0645\u0627\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u0628 \u06c1\u062c\u0631\u062a \u06a9\u0627 \u062d\u06a9\u0645 \u062f\u0631\u062c \u0630\u06cc\u0644 \u06c1\u06d2:<\/p>\n<pre><code class=\"language-text\">Understand\n\u2193\nCharacterize\n\u2193\nRefactor\n\u2193\nMigrate\n\u2193\nCompare\n\u2193\nCut over\n<\/code><\/pre>\n<p>AI \u0627\u0633 \u0639\u0645\u0644 \u06a9\u0648 \u0628\u06be\u06cc \u062a\u06cc\u0632 \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u0622\u067e \u06a9\u0648 \u0645\u0648\u0627\u0632\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0648\u0627\u0644\u06d2 \u0628\u0646\u0627\u0646\u06d2\u060c \u063a\u0644\u0637\u06cc\u0648\u06ba \u06a9\u0627 \u062a\u062c\u0632\u06cc\u06c1 \u06a9\u0631\u0646\u06d2\u060c \u0627\u06cc\u06a9 \u062c\u06cc\u0633\u06d2 \u0641\u0631\u0642\u0648\u06ba \u06a9\u0648 \u06af\u0631\u0648\u067e \u06a9\u0631\u0646\u06d2\u060c \u06a9\u0648\u0688 \u06a9\u06d2 \u0631\u0627\u0633\u062a\u0648\u06ba \u06a9\u0627 \u0645\u0639\u0627\u0626\u0646\u06c1 \u06a9\u0631\u0646\u06d2 \u0627\u0648\u0631 \u0679\u06cc\u0633\u0679 \u06a9\u06d2 \u0627\u0636\u0627\u0641\u06cc \u06a9\u06cc\u0633 \u062a\u062c\u0648\u06cc\u0632 \u06a9\u0631\u0646\u06d2 \u0645\u06cc\u06ba \u0645\u062f\u062f \u06a9\u0631 \u0633\u06a9\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u062a\u0627\u06c1\u0645\u060c \u06cc\u06c1 \u062a\u0639\u06cc\u0646 \u0646\u06c1\u06cc\u06ba \u06a9\u0631\u0646\u0627 \u0686\u0627\u06c1\u06cc\u06d2 \u06a9\u06c1 \u06a9\u0648\u0646 \u0633\u0627 \u0639\u0645\u0644 \u062f\u0631\u0633\u062a \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u0627\u0628 \u0628\u06be\u06cc \u062b\u0628\u0648\u062a\u060c \u0688\u0648\u0645\u06cc\u0646 \u0639\u0644\u0645\u060c \u0627\u0648\u0631 \u0627\u0646\u062c\u06cc\u0646\u0626\u0631\u0646\u06af \u06a9\u06d2 \u0641\u06cc\u0635\u0644\u06d2 \u06a9\u06cc \u0636\u0631\u0648\u0631\u062a \u06c1\u06d2.<\/p>\n<p>\u0627\u0645\u062a\u06cc\u0627\u0632\u06cc \u062c\u0627\u0646\u0686 \u06a9\u0627 \u0645\u0642\u0635\u062f \u063a\u06cc\u0631 \u06cc\u0642\u06cc\u0646\u06cc \u0635\u0648\u0631\u062a\u062d\u0627\u0644 \u06a9\u0648 \u0645\u06a9\u0645\u0644 \u0637\u0648\u0631 \u067e\u0631 \u062e\u062a\u0645 \u06a9\u0631\u0646\u0627 \u0646\u06c1\u06cc\u06ba \u06c1\u06d2\u06d4<\/p>\n<p>\u06cc\u06c1 \u063a\u06cc\u0631 \u06cc\u0642\u06cc\u0646\u06cc \u0635\u0648\u0631\u062a\u062d\u0627\u0644 \u06a9\u0648 \u0638\u0627\u06c1\u0631 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0628\u0627\u0631\u06d2 \u0645\u06cc\u06ba \u06c1\u06d2\u06d4 <strong>\u067e\u06c1\u0644\u06d2<\/strong> \u067e\u06cc\u062f\u0627\u0648\u0627\u0631\u06cc \u0679\u0631\u06cc\u0641\u06a9 \u06a9\u0648 \u062a\u0628\u062f\u06cc\u0644 \u06a9\u0631\u06cc\u06ba\u06d4<\/p>\n<p>\u0627\u0633 \u06a9\u06cc \u0648\u062c\u06c1 \u06cc\u06c1 \u06c1\u06d2 \u06a9\u06c1 \u06c1\u062c\u0631\u062a \u06a9\u06d2 \u062f\u0648\u0631\u0627\u0646\u060c \u06cc\u06c1 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0631\u0646\u0627 \u0645\u0641\u06cc\u062f \u06c1\u06d2 \u06a9\u06c1 \u0646\u06cc\u0627 \u0646\u0638\u0627\u0645 \u0645\u062e\u062a\u0644\u0641 \u0637\u0631\u06cc\u0642\u06d2 \u0633\u06d2 \u0628\u0631\u062a\u0627\u0624 \u06a9\u0631\u062a\u0627 \u06c1\u06d2\u06d4<\/p>\n<p>\u067e\u0631\u0627\u0646\u06d2 \u0633\u0633\u0679\u0645 \u06a9\u0648 \u0622\u0641 \u06a9\u0631\u0646\u06d2 \u06a9\u06d2 \u0628\u0639\u062f \u0627\u0633\u06d2 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0631\u0646\u0627 \u0632\u06cc\u0627\u062f\u06c1 \u0645\u06c1\u0646\u06af\u0627 \u06c1\u06d2\u06d4<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u0648\u0631\u0627\u062b\u062a \u06a9\u06cc \u0645\u0646\u062a\u0642\u0644\u06cc \u06a9\u0627 \u0633\u0628 \u0633\u06d2 \u062e\u0637\u0631\u0646\u0627\u06a9 \u0644\u0645\u062d\u06c1 \u0636\u0631\u0648\u0631\u06cc \u0646\u06c1\u06cc\u06ba \u06c1\u06d2 \u06a9\u06c1 \u062c\u0628 \u0622\u067e \u0627\u06cc\u06a9 \u0646\u06cc\u0627 \u0646\u0641\u0627\u0630 \u0644\u06a9\u06be\u0646\u0627 \u0634\u0631\u0648\u0639 \u06a9\u0631\u06cc\u06ba\u06d4 \u0646\u06cc\u0627 \u0639\u0645\u0644 \u062f\u0631\u0622\u0645\u062f \u0645\u06a9\u0645\u0644 \u06c1\u0648\u062a\u0627 \u062f\u06a9\u06be\u0627\u0626\u06cc \u062f\u06d2 \u0631\u06c1\u0627 \u06c1\u06d2\u06d4 \u0622\u067e \u06a9\u0627 \u06a9\u0648\u0688 \u0645\u0631\u062a\u0628 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u060c \u0622\u067e \u06a9\u06d2 \u0679\u06cc\u0633\u0679 \u067e\u0627\u0633 \u06c1\u0648\u062a\u06d2 \u06c1\u06cc\u06ba\u060c \u0622\u067e \u06a9\u0627 \u0641\u0646 \u062a\u0639\u0645\u06cc\u0631 \u0635\u0627\u0641 \u0633\u062a\u06be\u0631\u0627 \u06c1\u0648\u062a\u0627 \u06c1\u06d2\u060c \u0627\u0648\u0631 \u0622\u067e \u06a9\u06cc \u0646\u0626\u06cc \u0633\u0631\u0648\u0633 \u062a\u06cc\u0632\u06cc [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-29330","post","type-post","status-publish","format-standard","hentry","category-blog"],"_links":{"self":[{"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/posts\/29330","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/comments?post=29330"}],"version-history":[{"count":0,"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/posts\/29330\/revisions"}],"wp:attachment":[{"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/media?parent=29330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/categories?post=29330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/umang.pk\/en_us\/wp-json\/wp\/v2\/tags?post=29330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}