한 테스트를 다른 테스트 결과에 의존하게 만드는 방법은 무엇입니까?


13

코드의 모든 곳 에서 다른 많은 클래스가 사용하는 일반적인 정적 메소드를 제공하는 유틸리티 클래스가 있다고 가정 해 봅시다 .

유틸리티 테스트 중 하나라도 통과하지 못하면 테스트가 실패하도록 유틸리티 소비자에 대한 단위 테스트를 어떻게 설계 하시겠습니까? 유틸리티 클래스 테스트가 모두 녹색인지 직접 확인해야합니까?

예를 들어 메시지 파서가 사용하는 메시지 스플리터 유틸리티가 있습니다. 메시지 파서가 테스트되기 전에 메시지 스플리터가 올바르게 작동하는지 확인하고 싶습니다.

두 가지 모두에 대한 테스트를 작성했지만 두 테스트를 연결하고 다른 테스트 결과에 따라 하나의 테스트를 만드는 방법이 있습니까?

이에 적합한 태그를 찾을 수 없지만 Visual Studio의 단위 테스트 엔진을 사용하고 있습니다.


1
유틸리티가 실패하면 파서가 제대로 작동하지 않는다는 것을 알고 있습니다. 그러나 테스트를 실행하면 유틸리티 테스트가 실패 함을 알 수 있습니다. 다른 테스트에도 실패하는 이유는 무엇입니까?
Eugen Martynov 2019

1
나는 이것을 원하는 사람에 대해 들어 본 적이 없습니다. 무엇을 달성하려고합니까?
Esben Skov Pedersen


유틸리티 기능 중 일부를 사용하여 파서 테스트를 위해 데이터를 준비하므로 다른 것을 테스트하기 전에 유틸리티가 올바르게 작동하는지 절대적으로 확인하고 싶습니다.
t3chb0t

3
@ t3chb0t 유틸리티가 작동하는지 확인하려면 유틸리티를 확인하기 위해 단위 테스트를 작성해야합니다. 단위 테스트는 원 자성이어야합니다. 단일 구성 요소 만 테스트하기를 원합니다.
maple_shaft

답변:


11

시스템의 모든 결함이 정확히 하나의 테스트를 통과 하는지 확인할 필요는 없습니다 .

테스트 스위트에는 하나의 작업이 있습니다. 알려진 결함이 없는지 확인합니다. 결함이있는 경우 하나의 테스트가 실패하거나 10 개이면 문제가되지 않습니다. 테스트 스위트에 실패 하면 실패한 테스트 를 계산 하여 프로그램이 얼마나 "나쁜"지를 측정하려고 시도해도 실패합니다. 올바른 방법으로 회귀 테스트를 사용합니다. 테스트 스위트는 코드를 게시하기 전에 모든 테스트를 통과해야 합니다.

그들은 불완전한 기능을 테스트하는 경우 검사를 생략에 유효한 이유는 하고 그들이 시험에 예정하고있는 일을 실행하는 동안보다 효율적으로 사용에 넣어 수 시간의 과도한 양을. (이것은 엄격한 테스트 중심 개발을 연습하지 않는 경우에만 문제가되지만 결국 올바른 선택입니다.)

그렇지 않으면, 테스트 스위트를 무엇이 잘못되었는지 정확하게 알려주는 표시기로 만들려고하지 마십시오. 절대 정확하지 않으며 절대로 안됩니다. 같은 실수를 두 번하지 않도록 보호해야합니다. 그게 전부입니다.


8

툴링에 따라 다르지만 아마도 할 수는 없습니다.

일부 단위 테스트 프레임 워크 ( 예 : PHPUnit 사용)를 사용하면 한 수준에서 실패한 테스트가 다른 테스트를 실행하지 않도록 테스트를 '연쇄'할 수 있습니다. 그러나 이것이이 상황에 대한 문제를 해결할 것이라고 의심합니다.

보장 된 테스트 순서 실행을 허용하지 않으면 테스트가 서로 분리되고 일반적으로 좋은 것으로 간주됩니다. 테스트가 자체적으로 실행될뿐만 아니라 다른 테스트를 위해 데이터를 제공 할 경우 어떻게 될지 상상해보십시오.

이러한 유틸리티 방법을 별도의 솔루션 또는 테스트 범주에 넣을 수 있습니다. 테스트 러너에서 시각적으로 눈에 띄는 지 확인하십시오. 또는이 범주의 테스트가 실패하면이 범주가 먼저 실행되고 다른 테스트는 실행하지 않아야합니다 *. 이러한 테스트 중 하나가 실패하면 실패는 아마도 모든 테스트에 걸쳐 진행되므로 테스트를 실행하는 사람이 먼저 이러한 실패한 테스트를 수정하여 시작을 알도록해야합니다. 단위 테스트와 통합 테스트도 마찬가지입니다. 단위 테스트에 실패하면 통합 테스트에서 캐스케이드가 발생하여 모든 종류의 장애가 발생합니다. 단위 및 통합 테스트가 실패하면 단위 테스트를 확인하여 시작한다는 것을 모두 알고 있습니다 ...

* 자동 빌드 또는 테스트 스크립트를 사용하면이 범주를 먼저 실행하고 결과를 확인하고 첫 번째 테스트 배치가 통과하는 경우에만 다른 테스트를 실행할 수 있습니다.


5

단위 테스트 원자를 유지하십시오. 자동화 된 테스트 코드도 코드 기반의 일부이지만 자체 테스트 중이 아니므로 가능한 간단하고 명확하게 유지하십시오.

질문에보다 직접적으로 대답하기 위해 테스트 실행 순서를 보장 할 수 없으므로 다른 테스트를 실행하기 전에 유틸리티 테스트가 성공하도록 보장 할 방법이 없습니다. 따라서 모든 테스트에 대해 단일 테스트 스위트를 사용하면서 원하는 것을 달성 할 수있는 보장 된 방법이 없습니다.

유틸리티를 자체 솔루션으로 이동하고 현재 프로젝트에서 결과 dll에 대한 참조를 추가 할 수 있습니다.


4

요약하자면, 도구 이외의 용도로 도구 / 기술을 사용하고 싶지 않습니다.

당신이하려는 것은 CI (연속 통합) 연습으로 쉽게 해결할 수있는 관심사처럼 들립니다.

이렇게하면 이미 제안한대로 테스트를 원 자성으로 유지하고 CI가 테스트를 확인하도록 할 수 있습니다.

테스트가 실패하면 코드가 게시되지 않도록 설정할 수 있습니다.


4

항상 응용 프로그램 수준 코드와 프레임 워크 수준 코드를 구분하려고하는 습관이 있으므로, 자주 설명하는 문제가 발생했습니다. 일반적으로 응용 프로그램 수준 코드를 테스트하기 전에 모든 프레임 워크 수준 코드를 테스트하기를 원합니다. . 또한 프레임 워크 수준 코드 내에서도 다른 모든 프레임 워크 모듈에서 사용하는 일부 기본 프레임 워크 모듈이있는 경향이 있으며, 기본 사항에 문제가있는 경우 실제로 다른 테스트는 필요하지 않습니다.

불행히도, 테스트 프레임 워크 공급 업체는 자신의 창작물이 어떻게 사용되어야하는지에 대해 다소 딱딱한 아이디어를 갖는 경향이 있으며, 이러한 아이디어를 보호하는 반면 프레임 워크를 사용하는 사람들은 의심없이 의도 된 사용법을 받아들이는 경향이 있습니다. 실험과 혁신을 방해하기 때문에 문제가됩니다. 나는 다른 모든 사람들에 대해 모른다. 그러나 나는 이상한 방식으로 무언가를 시도하는 자유를 선호하고, 자유를 가지지 않고 기존 방식보다 결과가 나아지는지 나 자신을 위해보고 싶다. 처음부터 내 방식대로 해

제 생각에는 테스트 종속성이 가장 좋을 것입니다. 그 대신에 테스트 실행 순서를 지정하는 기능이 차선책 일 것입니다.

테스트 순서 문제를 해결하는 유일한 방법은 테스트 프레임 워크가 알파벳 순서로 테스트를 실행하는 경향을 이용하기 위해 신중하게 이름을 지정하는 것입니다.

C #을 사용한 광범위한 테스트와 관련하여 아직 아무것도하지 않았기 때문에 Visual Studio에서 이것이 어떻게 작동하는지 알지 못하지만 전세계 Java 환경에서는 다음과 같이 작동합니다. 프로젝트의 소스 폴더에는 일반적으로 두 개의 하위 폴더가 있습니다. 하나는 프로덕션 코드를 포함하는 "main"이고 테스트 코드를 포함하는 "test"입니다. "main"아래에는 소스 코드의 패키지 계층 구조와 정확히 일치하는 폴더 계층 구조가 있습니다. Java 패키지는 대략 C # 네임 스페이스에 해당합니다. C #에서는 폴더 계층 구조를 네임 스페이스 계층 구조와 일치시킬 필요가 없지만 그렇게하는 것이 좋습니다.

이제 사람들이 Java 세계에서 일반적으로하는 일은 "test"폴더 아래에서 "main"폴더 아래에있는 폴더 계층 구조 를 미러링 하여 각 테스트가 테스트하는 클래스와 정확히 동일한 패키지에 있다는 것입니다. 이것의 근거는 테스트 클래스가 테스트중인 클래스의 패키지 개인 멤버에 액세스해야하기 때문에 테스트 클래스는 테스트중인 클래스와 동일한 패키지에 있어야한다는 것입니다. 세계의 C # 측면에는 네임 스페이스 로컬 가시성 같은 것이 없으므로 폴더 계층 구조를 미러링 할 이유가 없지만 C # 프로그래머는 폴더를 구성 할 때 동일한 원칙을 따르지 않습니다.

어쨌든, 테스트 클래스가 구현이 아닌 인터페이스를 테스트하는 경향이 있기 때문에 테스트 클래스가 테스트중인 클래스의 패키지 로컬 멤버에 액세스 할 수있게한다는이 모든 아이디어를 발견했습니다. 따라서 테스트의 폴더 계층 구조는 프로덕션 코드의 폴더 계층 구조를 미러링하지 않아도됩니다.

그래서 내가하는 일은 테스트 폴더 (의미, 패키지)의 이름을 다음과 같이 지정하는 것입니다.

t001_SomeSubsystem
t002_SomeOtherSubsystem
t003_AndYetAnotherSubsystem
...

이렇게하면 "SomeSubsystem"에 대한 모든 테스트가 "SomeOtherSubsystem"에 대한 모든 테스트 전에 실행되며, "AndYetAnotherSubsystem"등에 대한 모든 테스트 전에 실행됩니다.

폴더 내에서 개별 테스트 파일의 이름은 다음과 같습니다.

T001_ThisTest.java
T002_ThatTest.java
T003_TheOtherTest.java

물론 최신 IDE에는 몇 번의 클릭과 키 입력만으로 전체 패키지 (및 모든 하위 패키지 및 해당 패키지를 참조하는 모든 코드)의 이름을 바꿀 수있는 강력한 리팩토링 기능이 있습니다.


2
I don't know about everyone else, but I would prefer to have the freedom to try to do something in an odd way, and see for myself whether the results are better or worse++ 메이트. 나는 솔루션을 좋아한다는 것을 모르지만 거기에 표시 한 태도가 마음에 든다.
RubberDuck
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.