рдпреВрдирд┐рдЯ рдЕрднреНрдпрд╛рд╕ рдкрд░реАрдХреНрд╖рдг

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреНрд░рдХрд╛рд╢рди рджрд┐рдЦрд╛рдИ рджрд┐рдП рд╣реИрдВ рдФрд░ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред рд╡рд┐рд╖рдп рдХрд╛рдлреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдФрд░ рдЗрд╕реЗ рд╢реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕рдордп рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЗ рдХреЛ рд╕рдорд░реНрдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рд╣рдорд╛рд░реА рдЯреАрдо рдореЗрдВ, рд╣рдо рдПрдХ рд╡рд░реНрд╖ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рд╕реЗ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖ рдФрд░ рдЖрдЦрд┐рд░рдХрд╛рд░ рд╣рдореЗрдВ рдХрд┐рд╕ рддрд░рд╣ рдХрд╛ рдЕрдиреБрднрд╡ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖред

рдореБрдЭреЗ рддреБрд░рдВрдд рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЙрджрд╛рд╣рд░рдг C # рднрд╛рд╖рд╛ рдФрд░ .NET рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рджрд┐рдП рдЧрдП рд╣реИрдВред рддрджрдиреБрд╕рд╛рд░, рдЕрдиреНрдп рднрд╛рд╖рд╛рдУрдВ / рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдореЗрдВ, рджреГрд╖реНрдЯрд┐рдХреЛрдг рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП ...

рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдЗрд╕ рддрдереНрдп рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХрд┐ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдЙрддреНрдкрд╛рдж рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдореБрдЦреНрдп рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЧрддрд┐ рд╣реИред рдпрджрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рд▓реЙрдиреНрдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдбреЗрд╡рд▓рдкрд░ рдмреНрд░реЗрдХ рд▓реЗ рд╕рдХрддрд╛ рд╣реИ (рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рд╕реНрдореЛрдХ рдмреНрд░реЗрдХ рдХреЗ рд▓рд┐рдП), рддреЛ рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓реЙрдиреНрдЪ рдХрдо рдФрд░ рдХрдо (рдлрд┐рд░ рд╕реЗ, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдирд┐рдХреЛрдЯреАрди рдХреА рдЕрдзрд┐рдХрддрд╛ рдХреЗ рдбрд░ рдХреЗ рдХрд╛рд░рдг) рд╣реЛрдВрдЧреЗред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдпрд╣ рдкрддрд╛ рдЪрд▓ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рдЪрд▓реЗрдВрдЧреЗ рдФрд░ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдЕрд░реНрде рдЦреЛ рдЬрд╛рдПрдЧрд╛ред рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рдХрд┐рд╕реА рднреА рд╕рдордп рдкреВрд░реЗ рдЯреЗрд╕реНрдЯ рд╕реВрдЯ рдХреЛ рдЪрд▓рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдФрд░ рдЗрд╕ рд╕реЗрдЯ рдХреЛ рдЬрд┐рддрдиреА рдЬрд▓реНрджреА рд╣реЛ рд╕рдХреЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдЧрддрд┐ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдЯреЗрд╕реНрдЯ рдЫреЛрдЯреЗ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП

рдЖрджрд░реНрд╢ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рддрд┐ рдкрд░реАрдХреНрд╖рдг рдПрдХ рдЬреЛрд░ рджреЗрддрд╛ рд╣реИред рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХреА рдЧрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЯреБрдХрдбрд╝рд╛ рдЬрд┐рддрдирд╛ рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛, рдкрд░реАрдХреНрд╖рдг рдЙрддрдиреА рд╣реА рддреЗрдЬреА рд╕реЗ рдЪрд▓реЗрдЧрд╛ред

рд╡реИрд╕реЗ, рдбрд┐рдЬрд╛рдЗрди рдХреЗ рд╡рд┐рд╖рдп рдкрд░ред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдкрд╕рдВрдж рдХрд░рддрд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ "рдЕрд░реЗрдВрдЬ-рдПрдХреНрдЯ-рдПрд╢реНрдпреЛрд░" рдХреЗ рд░реВрдк рдореЗрдВ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЗрд╕рдХрд╛ рд╕рд╛рд░ рдПрдХ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдкреВрд░реНрд╡ рд╢рд░реНрдд рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╣реИ (рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХрд╛ рдкреНрд░рд╛рд░рдВрдн,
рдкреНрд░реАрд╕реЗрдЯ), рдПрдХреНрд╢рди (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ) рдФрд░ рдкреЛрд╕реНрдЯрдХрдВрдбрд┐рд╢рди (рдЬреЛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рдкрд░рд┐рдгрд╛рдо)ред рдпрд╣ рдбрд┐рдЬрд╝рд╛рдЗрди рдкрд░реАрдХреНрд╖рдг рдХреА рдкрдардиреАрдпрддрд╛ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИ
рдкрд░реАрдХреНрд╖рдг рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд▓реЗрдЦрди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдпрджрд┐ рд╡рд┐рдХрд╛рд╕ JetBrains рд╕реЗ ReSharper рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЗрд╕ рдХреЗ рд▓рд┐рдП рд░рд┐рдХреНрдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

[Test] public void Test_$METHOD_NAME$() { //arrange $END$ //act //assert Assert.Fail("Not implemented"); } 


рдФрд░ рдлрд┐рд░ рдкрд░реАрдХреНрд╖рдг, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛, рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ (рд╕рднреА рдирд╛рдо рдХрд╛рд▓реНрдкрдирд┐рдХ рд╣реИрдВ, рд╕рдВрдпреЛрдЧ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╣реИрдВ):

 [Test] public void Test_ForbiddenForPackageChunkWhenPackageNotFound() { //arrange var packagesRepositoryMock = _mocks.Create<IPackagesRepository>(); packagesRepositoryMock .Setup(r => r.FindPackageAsync(_packageId)) .Returns(Task<DatabasePackage>.Factory.StartNew(() => null)); Register(packagesRepositoryMock.Object); //act var message = PostChunkToServer(new byte[] { 1, 2, 3 }); //assert _mocks.VerifyAll(); Assert.That(message.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden)); } 


рдЯреЗрд╕реНрдЯ рдХреЛ рдкрд░реНрдпрд╛рд╡рд░рдг (рдбреЗрдЯрд╛рдмреЗрд╕, рдиреЗрдЯрд╡рд░реНрдХ, рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо) рд╕реЗ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП

рдпрд╣ рдЖрдЗрдЯрдо рд╢рд╛рдпрдж рд╕рднреА рдХрд╛ рд╕рдмрд╕реЗ рд╡рд┐рд╡рд╛рджрд╛рд╕реНрдкрдж рд╣реИред рдЕрдХреНрд╕рд░ рд╕рд╛рд╣рд┐рддреНрдп рдореЗрдВ рдРрд╕реЗ рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдЯреАрдбреАрдбреА рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдпрд╛ рдЯреЗрд▓реАрдлреЛрди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рд╕реЗ рдЕрд▓рдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдбреЗрд╡рд▓рдкрд░, рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд▓реМрдЯрдХрд░, рд░реЛрдЬрдорд░реНрд░рд╛ рдХреЗ рдХрд╛рдо рдореЗрдВ рдЬреНрдЮрд╛рди рдФрд░ рдХреМрд╢рд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред рдХреБрдЦреНрдпрд╛рдд рдХреИрд▓рдХреБрд▓реЗрдЯрд░ рдХреЗ рд╕рдорд╛рди рд╕рд░рд▓рддрдо рдорд╛рдорд▓реЗ, рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдмрд╛рдХреА рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдПрдХ рд╣реА рд░реЗрд▓ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред рдирддреАрдЬрддрди, рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдкрд░ рд╕рдордп рдмрд┐рддрд╛рдиреЗ рдХреА рд╕рдордЭ рдХреНрдпреЛрдВ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддреА рд╣реИ рдпрджрд┐ рд╕рд░рд▓ рдХреЛрдб рдХреЛ рд╡реИрд╕реЗ рднреА рдбрд┐рдмрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЬрдЯрд┐рд▓ рдХреЛрдб рдХреЛ рд╡реИрд╕реЗ рднреА рдкрд░реАрдХреНрд╖рдг рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдпрд╛ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдареАрдХ рд╣реИред рддреЛ, рдХрдо рд╕реЗ рдХрдо, рдЖрдк рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдореВрд▓ рдХрд╛ рдЧрдарди рдХрд░рддрд╛ рд╣реИред рдПрдХрдорд╛рддреНрд░ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдЕрд▓рдЧрд╛рд╡ рдФрд░ рдЙрдирдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдЧрддрд┐ рдХреЗ рдмреАрдЪ рд╕рдВрддреБрд▓рди рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реБрдП, рд╕рдмрд╕реЗ рдХреБрд╢рд▓ рддрд░реАрдХреЗ рд╕реЗ рдмрд╛рд╣рд░реА рд╡рд╛рддрд╛рд╡рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ?

рдХреЗрд╕ 1. рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рд▓реЗрдпрд░ (MS SQL рд╕рд░реНрд╡рд░)

рдпрджрд┐ рдХрд┐рд╕реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ MS SQL рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП MS SQL рд╕рд░реНрд╡рд░ (рдПрдХреНрд╕рдкреНрд░реЗрд╕, рдПрдВрдЯрд░рдкреНрд░рд╛рдЗрдЬ рдпрд╛ рдбреЗрд╡рд▓рдкрд░ рд╕рдВрд╕реНрдХрд░рдг) рдХреЗ рд╕реНрдерд╛рдкрд┐рдд рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдПрдХ рд╕рдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ MS SQL рдкреНрд░рдмрдВрдзрди рд╕реНрдЯреВрдбрд┐рдпреЛ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдорд╛рдирдХ рддрдВрддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рджреГрд╖реНрдЯрд┐рдХреЛрдг рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рддреИрдирд╛рдд рдХрд░рдирд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, NUnit рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп SetUp рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╡рд┐рдзрд┐ рдореЗрдВ), рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рднрд░рдирд╛, рдФрд░ рдЗрди рдкреНрд░рд╕рд┐рджреНрдз рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рдкрд░ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдпрд╛ рдЧреЗрдЯрд╡реЗ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд╣рд╛рд░реНрдб рдбрд┐рд╕реНрдХ рдкрд░ рдФрд░ рдореЗрдореЛрд░реА рдореЗрдВ рдЙрди рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рд░реИрдо рдбрд┐рд╕реНрдХ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдФрд░ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдлрд┐рд▓рд╣рд╛рд▓ рдореИрдВ рдЬрд┐рд╕ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд╡рд╣ рд╕реЙрдлреНрдЯрдкреЗрдпрд░ рд░реИрдо рдбрд┐рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рд░реИрдо рдбрд┐рд╕реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХреЛ I / O рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджреМрд░рд╛рди рд╣реЛрдиреЗ рд╡рд╛рд▓реА рджреЗрд░реА рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓рддреА рд╣реИ рдЬреЛ рддрдм рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд╣рд╛рд░реНрдб рдбрд┐рд╕реНрдХ рдкрд░ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдмреЗрд╢рдХ, рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрджрд░реНрд╢ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХреЗ рд▓рд┐рдП рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рджреВрд╕рд░реА рдУрд░, рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рдХрд┐ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдмрд╛рд░ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдпрд╛ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдкрд░реНрдпрд╛рдкреНрдд), рдпрд╣ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЗрддрдиреА рдмреЛрдЭ рдирд╣реАрдВ рд▓рдЧрддреА рд╣реИред рдФрд░ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд▓рд╛рдн рдХрд╛рдлреА рд▓реБрднрд╛рд╡рдирд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрд░рддреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд╕рд╣реА рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

рд╡реИрд╕реЗ, рдпрджрд┐ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ MS SQL рд╕рд░реНрд╡рд░ рдореЗрдВ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП LINQ2SQL рдФрд░ SMO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рддреЛ рдЖрдк рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рд▓реЗрдпрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

рдХреЛрдб
 public abstract class DatabaseUnitTest<TContext> where TContext : DataContext { [TestFixtureSetUp] public void FixtureSetUp() { CreateFolderForTempDatabase(); } [SetUp] public void BeforeTestExecuting() { RestoreDatabaseFromOriginal(); RecreateContext(); } [TestFixtureTearDown] public void FixtureTearDown() { KillDatabase(); } protected string ConnectionString { get { return String.Format(@"Data Source={0};Initial Catalog={1};Integrated Security=True", TestServerName, TestDatabaseName); } } protected TContext Context { get; private set; } protected string TestDatabaseOriginalName { get { return "Database"; } } protected string ProjectName { get { return "CoolProject"; } } protected void RecreateContext() { Context = (TContext) Activator.CreateInstance(typeof(TContext), ConnectionString); } private string FolderForTempDatabase { get { return String.Format(@"R:\{0}.DatabaseTests\", ProjectName); } } private string TestDatabaseName { get { return FolderForTempDatabase + ProjectName + ".Tests"; } } private string TestDatabaseOriginalFileName { get { return Path.Combine(TestDatabaseDirectory, TestDatabaseOriginalName + ".mdf"); } } private string TestDatabaseFileName { get { return Path.Combine(TestDatabaseDirectory, TestDatabaseName + ".mdf"); } } private void CreateFolderForTempDatabase() { var directory = new DirectoryInfo(FolderForTempDatabase); if(!directory.Exists) { directory.Create(); } } private void RestoreDatabaseFromOriginal() { KillDatabase(); CopyFiles(); AttachDatabase(); } private void KillDatabase() { Server server = Server; SqlConnection.ClearAllPools(); if(server.Databases.Contains(TestDatabaseName)) { server.KillDatabase(TestDatabaseName); } } private void CopyFiles() { new FileInfo(TestDatabaseOriginalFileName).CopyTo(TestDatabaseFileName, true); string logFileName = GetLogFileName(TestDatabaseFileName); new FileInfo(GetLogFileName(TestDatabaseOriginalFileName)).CopyTo(logFileName, true); new FileInfo(TestDatabaseFileName).Attributes = FileAttributes.Normal; new FileInfo(logFileName).Attributes = FileAttributes.Normal; } private void AttachDatabase() { Server server = Server; if(!server.Databases.Contains(TestDatabaseName)) { server.AttachDatabase(TestDatabaseName, new StringCollection {TestDatabaseFileName, GetLogFileName(TestDatabaseFileName)}); } } private static string GetLogFileName(string databaseFileName) { return new Regex(".mdf$", RegexOptions.IgnoreCase).Replace(databaseFileName, "_log.ldf"); } private static Server Server { get { return new Server(TestServerName); } } private static string TestServerName { get { return "."; } } private static string TestDatabaseDirectory { get { var debugDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); DirectoryInfo binDirectory = debugDirectory.Parent; DirectoryInfo testProjectDirectory; if(binDirectory == null || (testProjectDirectory = binDirectory.Parent) == null) { throw new Exception(""); } return Path.Combine(testProjectDirectory.FullName, "Database"); } } } 


рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛:

 [TestFixture] public class ObjectFinderTest : DatabaseUnitTest<DatabaseDataContext> { [Test] public void Test_NullWhenObjectNotExists() { //arrange var fakeIdentifier = 0; var finder = new ObjectFinder(fakeIdentifier, ConnectionString); //act var foundObject = finder.Find(); //assert Assert.That(foundObject, Is.Null); } [Test] public void Test_SuccessfullyFound() { //arrange var insertedObject = ObjectsFactory.Create(); Context.Objects.InsertOnSubmit(insertedObject); Context.SubmitChanges(); var finder = new ObjectFinder(insertedObject.Id, ConnectionString); //act var foundObject = finder.Find(); //assert Assert.That(foundObject.Id, Is.EqualTo(insertedObject.Id)); Assert.That(foundObject.Property, Is.EqualTo(insertedObject.Property)); } } 


рджреЗрдЦрд╛! рд╣рдореЗрдВ рдбреЗрдЯрд╛рдмреЗрд╕ рдПрдХреНрд╕реЗрд╕ рд▓реЗрдпрд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рдорд┐рд▓рд╛ред

рдХреЗрд╕ 2. ASP.NET MVC WebAPI

WebAPI рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рддреЗ рд╕рдордп, рдПрдХ рдкреНрд░рд╢реНрди рдпрд╣ рд╣реИ рдХрд┐ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдП рддрд╛рдХрд┐ рдЖрдк рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ url рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рднреЗрдЬрддреЗ рд╕рдордп рд╕рд╣реА рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╣реА рдирд┐рдпрдВрддреНрд░рдХреЛрдВ рдкрд░ рд╕рд╣реА рддрд░реАрдХреЛрдВ рд╕реЗ рдХреЙрд▓рд┐рдВрдЧ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХреЗрдВред рдпрджрд┐ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдирд┐рдпрдВрддреНрд░рдХ рдХреА рдЬрд┐рдореНрдореЗрджрд╛рд░реА рдХреЗрд╡рд▓ рдХреЙрд▓ рдХреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд░реНрдЧ рдпрд╛ рдШрдЯрдХ рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░рдирд╛ рд╣реИ, рддреЛ рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд╡рд╛рд▓ рдХрд╛ рдЬрд╡рд╛рдм рдЗрд╕ рддрдереНрдп рд╕реЗ рдХрдо рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдХреБрдЫ рдРрд╕реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВ рдЬрд┐рд╕рдореЗрдВ рдирд┐рдпрдВрддреНрд░рдХ рдЖрд╡рд╢реНрдпрдХ HTTP рдЕрдиреБрд░реЛрдз рднреЗрдЬ рд╕рдХреЗ рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдорд╛рд░реНрдЧ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЛрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдЙрд╕реА рд╕рдордп, рдореИрдВ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдХреЛ рддреИрдирд╛рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП IIS рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдЪрд▓рд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рд╕реЗ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдЕрд▓рдЧ рд╣реЛрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓реЗрдЧреАред IIS рдХреЗ рд╕рд╛рде, рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ рдпрд╣ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛ред

рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, .NET рдлреНрд░реЗрдорд╡рд░реНрдХ 4.5 рдХреА рд░рд┐рд▓реАрдЬ рдХреЗ рд╕рд╛рде, рдкрд░реАрдХреНрд╖рдг рд░реВрдЯрд┐рдВрдЧ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХрд╛рдлреА рд╕рд░рд▓рддрд╛ рд╕реЗ рд╣рд▓ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЧрдпрд╛ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рд╡рд░реНрдЧреЛрдВ (рдПрдХрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ DI рдХрдВрдЯреЗрдирд░ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:

рдХреЛрдб
 public abstract class AbstractControllerTest<TController> where TController : ApiController { private HttpServer _server; private HttpClient _client; private UnityContainer _unityContainer; [SetUp] public void BeforeTestExecuting() { _unityContainer = new UnityContainer(); var configuration = new HttpConfiguration(); WebApiConfig.Register(configuration, new IoCContainer(_unityContainer)); _server = new HttpServer(configuration); _client = new HttpClient(_server); Register<TController>(); RegisterConstructorDependenciesAndInjectionProperties(typeof(TController)); } [TearDown] public void AfterTestExecuted() { _client.Dispose(); _server.Dispose(); _unityContainer.Dispose(); } protected TestHttpRequest CreateRequest(string url) { return new TestHttpRequest(_client, url); } protected void Register<T>(T instance) { Register(typeof(T), instance); } private void Register(Type type, object instance) { _unityContainer.RegisterInstance(type, instance); } private void Register<T>() { _unityContainer.RegisterType<T>(); } private void RegisterConstructorDependenciesAndInjectionProperties(Type controllerType) { var constructors = controllerType.GetConstructors(); var constructorParameters = constructors .Select(constructor => constructor.GetParameters()) .SelectMany(constructorParameters => constructorParameters); foreach (var constructorParameter in constructorParameters) { RegisterMockType(constructorParameter.ParameterType); } var injectionProperties = controllerType.GetProperties() .Where(info => info.GetCustomAttributes(typeof(DependencyAttribute), false) .Any()); foreach (var property in injectionProperties) { RegisterMockType(property.PropertyType); } } private void RegisterMockType(Type parameterType) { dynamic mock = Activator.CreateInstance(typeof(Mock<>).MakeGenericType(parameterType), new object[] { MockBehavior.Default }); Register(parameterType, mock.Object); } } 

 public sealed class TestHttpRequest { private readonly HttpClient _client; private readonly Uri _uri; public TestHttpRequest(HttpClient client, string url) { _client = client; _uri = new Uri(new Uri("http://can.be.anything/"), url); } public void AddHeader(string header, object value) { _client.DefaultRequestHeaders.Add(header, value.ToString()); } public HttpResponseMessage Get() { return _client.GetAsync(_uri).Result; } public HttpResponseMessage Post(byte[] content) { return _client.PostAsync(_uri, new ByteArrayContent(content)).Result; } public HttpResponseMessage Put(byte[] content) { return _client.PutAsync(_uri, new ByteArrayContent(content)).Result; } public HttpResponseMessage Head() { var message = new HttpRequestMessage(HttpMethod.Head, _uri); return _client.SendAsync(message).Result; } } 


рдЕрдм рдЖрдк рдЗрди рд╡рд░реНрдЧреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдирд┐рдпрдВрддреНрд░рдХ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдХреНрд░рдордмрджреНрдз рджрд┐рдирд╛рдВрдХ рдФрд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╡рд░реНрдЧ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

 [TestFixture] public class MyControllerTest : AbstractControllerTest<MyController> { private MockRepository _mocks; protected override void OnSetup() { _mocks = new MockRepository(MockBehavior.Strict); } [Test] public void Test_GetDates() { //arrange var january = new DateTime(2013, 1, 1); var february = new DateTime(2013, 2, 1); var repositoryMock = _mocks.Create<IRepository>(); repositoryMock .Setup(r => r.GetDates()) .Returns(new[] {january, february}); Register(repositoryMock.Object); //act var dates = ExecuteGetRequest<DateTime[]>("/api/build-dates"); //assert _mocks.VerifyAll(); Assert.That(dates, Is.EquivalentTo(new[] { january, february })); } [Test] public void Test_GetPlatforms() { //arrange var platform1 = new Platform {Id=1, Name = "1"}; var platform2 = new Platform {Id=2, Name = "2"}; var repositoryMock = _mocks.Create<IRepository>(); repositoryMock .Setup(r => r.GetPlatforms()) .Returns(new[] { platform1, platform2 }); Register(repositoryMock.Object); //act var platforms = ExecuteGetRequest<Platform[]>("/api/platforms"); //assert _mocks.VerifyAll(); Assert.That(platforms, Is.EquivalentTo(new[] { platform1, platform2 })); } private T ExecuteGetRequest<T>(string uri) { var request = CreateRequest(url); var response = request.Get(); T result; response.TryGetContentValue(out result); return result; } } 


рдмрд╕ рдЗрддрдирд╛ рд╣реАред рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдгреЛрдВ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдХрд┐рдП рдЧрдП рд╣реИрдВред

рдХреЗрд╕ 3. рд╕рдм рдХреБрдЫ

рдФрд░ рд╕рдм рдХреБрдЫ рдХреЗ рд╕рд╛рде, рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдЬрд┐рдирдореЗрдВ рд╢реБрджреНрдз рддрд░реНрдХ рд╣реЛрддреЗ рд╣реИрдВ, рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрд╛рд╣рд░реА рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд┐рдП, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдЙрди рд▓реЛрдЧреЛрдВ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдкреНрд░рдХрд╛рд░ рд╕реЗ рдХреЗрдВрдЯ рдмреЗрдХ рдЯреАрдбреАрдбреА рдХреЗ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕рд╛рд╣рд┐рддреНрдп рдореЗрдВ рдкреЗрд╢ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдпрд╣рд╛рдВ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдЪрд╛рд▓ рдирд╣реАрдВ рд╣реИред

рдореИрдВ рдЬреЛрдбрд╝реВрдВрдЧрд╛ рдХрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдЬрд┐рдХ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓рд╛рдн рднреА рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ:


рдпрд╣ рд╢рд╛рдпрдж рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╕реВрдЪреАрдмрджреНрдз "рдмрдиреНрд╕" рд╣рдореЗрд╢рд╛ рддрд╛рдЬрд╛ рдФрд░ рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ рд╣реЛрдЧрд╛, "рдкрд░реАрдХреНрд╖рдг рдкрд╣рд▓реЗ" рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдзреАрдиред рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдПрдБ рдмрджрд▓ рдЧрдИ рд╣реИрдВ? рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝реЗрдВ, рдХреЛрдб рдмрджрд▓реЗрдВред рддреНрд░реБрдЯрд┐ рдареАрдХ рдХрд░реЗрдВ? рдПрдХ рдкрд░реАрдХреНрд╖рдг рдЬреЛрдбрд╝реЗрдВ, рдХреЛрдб рдмрджрд▓реЗрдВред рд╕рдмрд╕реЗ рдХрдард┐рди рд╣рд┐рд╕реНрд╕рд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреА рдзрд╛рд░рдгрд╛ рдХреЛ рдмрджрд▓рдирд╛ рд╣реИред рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЕрдХреНрд╕рд░ "рдореБрдЦреНрдп" рдХреЛрдб рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд┐рджреЗрд╢реА рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдЯреАрдбреАрдбреА рдХреЛ рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рдмрд╛рдзрд╛ рд╣реИред рдФрд░ рдЗрд╕реЗ рджреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╣ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рдЧрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдПрдХ рдкреВрд░реЗ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рд╣реИрдВред

рдЖрдЬ рддрдХ, рд╣рдорд╛рд░реА рдЯреАрдо рдЬрд┐рд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИ, рдЙрд╕рдореЗрдВ рд▓рдЧрднрдЧ 1,000 рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рд╣реИрдВред TeamCity рдкрд░ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдФрд░ рд▓реЙрдиреНрдЪ рдХрд╛ рд╕рдордп 4 рдорд┐рдирдЯ рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рд╣реИред рд▓реЗрдЦ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рдХреЛрдб рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдФрд░ рд╡рд┐рдХрд╛рд╕ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ, рд╕рд┐рд╕реНрдЯрдо рдХреА рд▓рдЧрднрдЧ рд╕рднреА рдкрд░рддреЛрдВ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд╣рдорд╛рд░рд╛ рдЕрдиреБрднрд╡ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред

Source: https://habr.com/ru/post/In191986/


All Articles