답변:
제 생각에 단위 테스트는 생산 코드와 별도의 어셈블리에 배치해야합니다. 다음은 생산 코드와 동일한 어셈블리에 단위 테스트를 배치하는 몇 가지 단점입니다.
나는 정말로 어떤 전문가도 모른다. 여분의 프로젝트 (또는 10)를 갖는 것은 사기가 아닙니다.
편집 : 빌드 및 배송에 대한 추가 정보
또한 자동화 된 빌드 프로세스는 생산 및 단위 테스트를 다른 위치에 배치하는 것이 좋습니다. 이상적으로, 단위 테스트 빌드 프로세스는 프로덕션 코드가 빌드 된 경우에만 실행되고 제품 파일을 단위 테스트 디렉토리에 복사합니다. 이렇게하면 배송 등을 위해 실제 비트가 분리됩니다. 또한 특정 디렉토리의 모든 테스트에서이 시점에서 자동화 된 단위 테스트를 실행하는 것은 매우 사소한 일입니다.
요약하자면 다음은 비트 및 기타 파일의 일일 빌드 및 테스트 및 배송에 대한 일반적인 아이디어입니다.
#if
. 이 사용자 정의 심볼은 CI 소프트웨어 스크립트에서 컴파일러 명령 줄 매개 변수를 사용하여 전환 할 수 있습니다. msdn.microsoft.com/en-us/library/4y6tbswk.aspx를 참조 하십시오 .
별도의 프로젝트이지만 동일한 솔루션에 있습니다. (테스트 및 프로덕션 코드를위한 별도의 솔루션을 사용하여 제품을 작업했습니다. 끔찍합니다. 항상 두 가지를 전환하고 있습니다.)
별도의 프로젝트에 대한 이유는 다른 사람들이 명시한 것입니다. 데이터 기반 테스트를 사용하는 경우 프로덕션 어셈블리에 테스트를 포함하면 상당한 양의 팽창이 발생할 수 있습니다.
프로덕션 코드의 내부 멤버에 액세스해야하는 경우 InternalsVisibleTo를 사용하십시오 .
[assembly:InternalsVisibleTo("UnitTestProjectName")]
에게는 프로젝트 AssemblyInfo.cs
파일에 추가한다는 의미 입니다.
프로덕션 코드로 테스트를 배포하는 것에 대한 이의 제기를 자주 이해하지 못합니다. 작은 마이크로 캡으로 팀을 이끌었습니다 (14 ~ 130 명). 우리는 6 개 정도의 Java 앱을 보유하고 있었고, 특정 분야에서 테스트를 수행하기 위해 테스트를 현장에 배치하는 것이 매우 중요하다는 것을 알았습니다.비정상적인 동작을 보이는 기계. 현장에서 임의의 문제가 발생하고 비용이 전혀 들지 않는 미스터리에서 수천 단위의 테스트를 던질 수 있었으며 설치 문제, 비정상적인 RAM 문제, 기계 관련 문제, 비정상적인 네트워크 문제, 기타 등등. 나는 현장에 시험을하는 것이 매우 귀중하다고 생각합니다. 또한 임의의 시간에 임의의 문제가 발생하기 때문에 단위 테스트가 이미 통지를 위해 실행 대기중인 상태로있는 것이 좋습니다. 하드 드라이브 공간이 저렴합니다. 데이터와 함수를 함께 유지하려고 노력하는 것처럼 (OO 디자인), 코드와 테스트를 함께 유지하는 데 근본적으로 가치있는 것이 있다고 생각합니다 (함수 + 함수를 검증하는 테스트).
테스트를 C # /. NET / Visual Studio 2008의 동일한 프로젝트에 배치하고 싶지만 여전히 달성하기에 충분하지는 않습니다.
FooTest.cs와 동일한 프로젝트에서 Foo.cs를 유지하면 얻을 수있는 큰 이점 중 하나는 클래스에 형제 테스트가 없을 때 개발자에게 지속적으로 알려줍니다! 이것은 더 나은 테스트 중심 코딩 관행을 장려합니다 ... 구멍이 더 분명합니다.
더 나은 캡슐화를 위해 코드와 동일한 프로젝트에 단위 테스트를 수행하십시오.
내부 메소드를 쉽게 테스트 할 수 있습니다. 즉, 내부에 있어야하는 메소드를 공개하지 않습니다.
또한 단위 테스트를 작성하는 코드에 가깝게 만드는 것이 좋습니다. 메소드를 작성할 때 동일한 프로젝트에 있기 때문에 해당 단위 테스트를 쉽게 찾을 수 있습니다. unitTests가 포함 된 어셈블리를 빌드 할 때 unitTest의 오류로 인해 컴파일러 오류가 발생하므로 빌드하기 위해 unittest를 최신 상태로 유지해야합니다. 별도의 프로젝트에서 단위 테스트를 수행하면 일부 개발자가 단위 테스트 프로젝트 빌드를 잊어 버리고 잠시 동안 깨진 테스트가 누락 될 수 있습니다.
컴파일 태그 (IF #Debug)를 사용하여 생산 코드에서 단위 테스트를 제거 할 수 있습니다.
자동 통합 테스트 (iUnit으로 제작)는 단일 프로젝트에 속하지 않으므로 별도의 프로젝트에 있어야합니다.
Release
빌드 에서 테스트를 실행할 수 없으며 "heisenbugs"가 거의 없음을 의미합니다 .
InternalsVisibleTo
하면 별도의 테스트 프로젝트에서 내부 메소드를 테스트 할 수 있습니다
Debug
, Approval
그리고 Release
; 모든 릴리스 최적화로 승인을 컴파일하십시오. 또한 일반적으로 단위 테스트는 처음에는 헤 이젠 버그를 감지하는 데 좋지 않습니다 (제 경험상). 당신은 그것들에 대한 특정한 통합 회귀 테스트를 필요로하는 경향이 있습니다. 그리고 그것들을 나란히 배치 할 수도 있습니다.
테스트하고있는 코드와 함께 파일에 테스트를 자주 배치하는 TypeScript 프로젝트에서 시간을 보낸 후 별도의 방법으로 유지하는 것보다이 방법을 선호했습니다.
그래서 최근에 새로운 .NET Core 프로젝트를 시작할 때 테스트 또는 테스트 어셈블리를 최종 릴리스와 함께 제공하지 않고 C # 프로젝트에서이 구조를 모방 할 수 있는지 확인하고 싶었습니다.
프로젝트 파일에 다음 줄을 넣으면 지금까지 잘 작동하는 것으로 보입니다.
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<Compile Remove="**\*.Tests.cs" />
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' != 'Release'">
<PackageReference Include="nunit" Version="3.11.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
</ItemGroup>
위의 내용은 Release
구성 에서 이름 *.Tests.cs
이 지정된 모든 파일 이 컴파일에서 제외되고 필요한 단위 테스트 패키지 참조가 제거되도록합니다.
릴리스 구성에서 클래스를 단위 테스트 할 수 있으려면 Release
이라고하는 에서 파생 된 새 구성을 만들면 ReleaseContainingTests
됩니다.
업데이트 : 이 기술을 잠시 사용한 후에도 VS 코드에서 아이콘을 사용자 정의하여 탐색기 창에서 테스트 (및 기타 사항)를 좀 더 두드러지게 만드는 것이 도움이되는 것을 알았습니다.
이렇게하려면 Material Icon Theme 확장을 사용하고 VS Code 환경 설정 JSON에 다음과 같은 것을 추가하십시오.
"material-icon-theme.files.associations": {
"*.Tests.cs": "test-jsx",
"*.Mocks.cs": "merlin",
"*.Interface.cs": "yaml",
}
단위 테스트는 항상 별도의 프로젝트에서 진행됩니다. 실제로 솔루션에있는 모든 프로젝트에 대해 별도의 테스트 프로젝트가 있습니다. 테스트 코드는 응용 프로그램 코드가 아니며 코드와 섞어서는 안됩니다. 적어도 TestDriven.Net을 사용하여 별도의 프로젝트로 유지하는 한 가지 이점은 테스트 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 해당 프로젝트의 모든 테스트를 실행하여 한 번의 클릭으로 전체 응용 프로그램 코드 라이브러리를 테스트 할 수 있다는 것입니다.
경우 NUnit과의 프레임 워크를 사용, 같은 프로젝트에서 테스트를 넣어 추가적인 이유가있다. 단위 테스트와 혼합 된 다음 프로덕션 코드 예제를 고려하십시오.
public static class Ext
{
[TestCase(1.1, Result = 1)]
[TestCase(0.9, Result = 1)]
public static int ToRoundedInt(this double d)
{
return (int) Math.Round(d);
}
}
여기서 단위 테스트는 테스트중인 코드에 대한 문서 및 사양으로 사용됩니다. 테스트가 별도의 프로젝트에있는 자체 문서화의 효과를 얻는 방법을 모르겠습니다. 함수 사용자는 테스트 케이스를보기 위해 테스트를 검색해야 할 것입니다.
업데이트 : 이러한 TestCase
속성 사용 이 NUnit 개발자가 의도 한 것이 아니라는 이유는 무엇입니까?
별도의 프로젝트에 넣었습니다. 어셈블리 이름은 일반적인 규칙으로 네임 스페이스 이름과 동일합니다. 따라서 Company.Product.Feature.sln이라는 프로젝트가 있으면 Company.Product.Feature.dll의 출력 (어셈블리 이름)을 갖습니다. 테스트 프로젝트는 Company.Product.Feature.Tests.sln이며 Company.Product.Feature.Tests.dll을 생성합니다.
단일 솔루션으로 유지하고 구성 관리자를 통해 출력을 제어하는 것이 가장 좋습니다. 기본 디버그 및 릴리스를 사용하는 대신 각 주요 브랜치 (개발, 통합, 프로덕션)에 대해 명명 된 구성이 있습니다. 구성을 설정 한 후에는 구성 관리자에서 "빌드"체크 상자를 클릭하여 구성을 포함하거나 제외 할 수 있습니다. (구성 관리자를 가져 오려면 솔루션을 마우스 오른쪽 단추로 클릭하고 구성 관리자로 이동하십시오.) Visual Studio에서 CM이 때때로 버그가 있음을 알았습니다. 몇 번, 프로젝트 및 / 또는 솔루션 파일로 이동하여 생성 한 대상을 정리해야했습니다.
또한 팀 빌드를 사용하는 경우 (그리고 다른 .NET 빌드 도구가 동일하다고 확신하는 경우) 빌드를 명명 된 구성과 연결할 수 있습니다. 예를 들어, "Production"빌드에 대한 단위 테스트를 빌드하지 않으면 빌드 프로젝트는이 설정을 인식 할 수 있으며 표시되어 있으므로 빌드 할 수 없습니다.
또한 빌드 머신에서 XCopy 드롭 오프를 수행했습니다. 스크립트는 * .Tests.Dll이라는 이름의 배포가 생략되는 것을 생략합니다. 간단하지만 효과가있었습니다.
나는 그것들을 별개로 유지한다고 말할 것입니다.
언급 된 다른 이유 외에도 코드와 테스트를 함께 사용하면 테스트 적용 범위 수가 왜곡됩니다. 단위 테스트 적용 범위를보고 할 때-단위 테스트를 실행할 때 테스트가 포함되므로보고 된 적용 범위가 더 높습니다. 통합 테스트 적용 범위에 대해보고하면 통합 테스트에서 단위 테스트가 실행되지 않으므로보고 된 적용 범위가 낮아집니다.
실제로 Flood NN 라이브러리 의 단위 테스트 프레임 워크에서 영감을 얻었습니다.Robert Lopez . 모든 단일 단위 테스트 클래스에 대해 서로 다른 프로젝트를 사용하며 모든 테스트를 컴파일하고 실행하는 기본 프로젝트뿐만 아니라 이러한 모든 프로젝트를 보유하는 하나의 솔루션이 있습니다.
깔끔한 것도 프로젝트의 레이아웃입니다. 소스 파일은 폴더에 있지만 VS 프로젝트의 폴더는 아래에 있습니다. 이를 통해 컴파일러마다 다른 하위 폴더를 만들 수 있습니다. 모든 VS 프로젝트는 코드와 함께 제공되므로 누구나 쉽게 모든 단위 테스트를 실행할 수 있습니다.
나는 이것이 매우 오래된 질문이라는 것을 알고 있지만 최근에 단위 테스트 습관을 별도의 프로젝트에서 동일한 프로젝트로 바꾸는 경험을 추가하고 싶습니다.
왜?
먼저 메인 프로젝트 폴더 구조를 테스트 프로젝트와 동일하게 유지하는 경향이 있습니다. 따라서 파일이 아래에 있으면 Providers > DataProvider > SqlDataProvider.cs
단위 테스트 프로젝트에서 동일한 구조를 만듭니다.Providers > DataProvider > SqlDataProvider.Tests.cs
그러나 프로젝트가 점점 커지고 나면 파일을 한 폴더에서 다른 폴더로 이동하거나 한 프로젝트에서 다른 프로젝트로 이동하면 파일을 단위 테스트 프로젝트와 동기화하는 작업이 매우 번거로워집니다.
둘째, 테스트 할 클래스에서 단위 테스트 클래스로 이동하는 것이 항상 쉬운 것은 아닙니다. JavaScript 및 Python에서는 더 어렵습니다.
최근에, 내가 만든 모든 단일 파일 (예 SqlDataProvider.cs
:)을 테스트 접미어로 다른 파일을 만들고 있다는 것을 연습하기 시작했습니다.SqlDataProvider.Tests.cs
처음에는 파일과 라이브러리 참조가 부풀어 오르는 것처럼 보이지만 장기적으로는 이동 파일 증후군을 한눈에 제거하고 테스트 대상인 모든 단일 파일에 쌍 파일이 있는지 확인합니다. 와 .Tests
접미사. 별도의 프로젝트를 보지 않고 테스트 파일 (나란히 있기 때문에)으로 쉽게 이동할 수 있습니다.
프로젝트를 스캔하고 .Tests 파일이없는 클래스를 식별하여 소유자에게보고하는 비즈니스 규칙을 작성할 수도 있습니다. 또한 테스트 러너에게 .Tests
클래스 를 대상으로 쉽게 알릴 수 있습니다.
특히 Js와 Python의 경우 다른 경로에서 참조를 가져올 필요가 없으며 테스트중인 대상 파일의 동일한 경로를 사용할 수 있습니다.
나는이 관행을 잠시 동안 사용하고 있으며, 프로젝트 규모와 유지 보수성 및 프로젝트에 새로 온 사람들을위한 학습 곡선 사이의 균형이 매우 합리적인 것이라고 생각합니다.
다른 사람들이 대답했듯이- 별도의 프로젝트에서 테스트를하십시오.
언급되지 않은 한 가지는 실제로 파일 nunit3-console.exe
이외의 다른 것에 대해서는 실행할 수 없다는 사실 .dll
입니다.
TeamCity를 통해 테스트를 실행하려는 경우 문제가 발생합니다.
콘솔 응용 프로그램 프로젝트가 있다고 가정 해 봅시다. 컴파일하면 실행 파일 .exe
이 bin
폴더로 반환 됩니다.
로부터 nunit3-console.exe
해당 콘솔 응용 프로그램에 정의 된 모든 테스트를 실행 할 수 없습니다.
즉, 콘솔 응용 프로그램은 exe
파일을 반환 하고 클래스 라이브러리는dll
파일을 합니다.
나는 오늘 이것에 조금 물 렸고 그것은 짜증 난다 :(
별도의 프로젝트이지만 동일한 svn을 공유해야하는지 여부에 대해 스스로 토론합니다. 현재는 별도의 svn 저장소를 제공하고 있습니다.
"MyProject"-프로젝트 자체
그리고 하나는
"MyProjectTests"-MyProject와 관련된 테스트 용.
이것은 상당히 깨끗하며 프로젝트에 대한 커밋과 테스트에 대한 커밋이 상당히 분리되어 있다는 장점이 있습니다. 또한 필요한 경우 테스트를 해제하지 않고도 프로젝트의 svn을 넘길 수 있습니다. 또한 테스트 및 프로젝트에 대해 branch / trunk / tag 디렉토리를 가질 수 있음을 의미합니다.
그러나 각 프로젝트마다 단일 svn 저장소에 다음과 같은 것이 점점 더 기울어지고 있습니다.
MyProject | \ 트렁크 | | \ 코드 | \ 테스트 | \ 태그 | | \ 0.1 | | | \ 코드 | | \ 테스트 | \ 0.2 | | \ 코드 | \ 테스트 지점 \ 마이 포크 | \ 코드 \테스트
다른 사람들이이 솔루션에 대해 어떻게 생각하는지 알고 싶습니다.