예를 들어, 코드가 0-10에서 임의의 int를 생성하고 각 결과에 대해 다른 분기를 사용하는 경우 이러한 코드에서 100 % 명령문 적용 범위를 보장하기 위해 테스트 스위트를 어떻게 설계 할 수 있습니까?
Java에서 코드는 다음과 같습니다.
int i = new Random().nextInt(10);
switch(i)
{
    //11 case statements
}
답변
랜덤에 대한 래퍼를 만들어야한다는 전적으로 동의하는 David의 대답을 확장하십시오 . 나는 비슷한 질문 에서 앞서 그것에 대해 거의 같은 대답을 썼 으므로 여기에 “Cliff ‘s notes version”이 있습니다.
먼저 래퍼를 인터페이스 (또는 추상 클래스)로 작성해야합니다.
public interface IRandomWrapper {
    int getInt();
}
이에 대한 구체적인 클래스는 다음과 같습니다.
public RandomWrapper implements IRandomWrapper {
    private Random random;
    public RandomWrapper() {
        random = new Random();
    }
    public int getInt() {
        return random.nextInt(10);
    }
}
수업이 다음과 같다고 가정 해보십시오.
class MyClass {
    public void doSomething() {
        int i=new Random().nextInt(10)
        switch(i)
        {
            //11 case statements
        }
    }
}
IRandomWrapper를 올바르게 사용하려면 클래스를 수정하여 생성자 또는 설정자를 통해 멤버로 가져와야합니다.
public class MyClass {
    private IRandomWrapper random = new RandomWrapper(); // default implementation
    public setRandomWrapper(IRandomWrapper random) {
        this.random = random;
    }
    public void doSomething() {
        int i = random.getInt();
        switch(i)
        {
            //11 case statements
        }
    }
}
이제 래퍼를 조롱하여 래퍼로 클래스의 동작을 테스트 할 수 있습니다. 조롱 프레임 워크를 사용 하여이 작업을 수행 할 수 있지만 직접 수행하는 것도 쉽습니다.
public class MockedRandomWrapper implements IRandomWrapper {
   private int theInt;
   public MockedRandomWrapper(int theInt) {
       this.theInt = theInt;
   }
   public int getInt() {
       return theInt;
   }
}
당신의 수업은 IRandomWrapper당신 처럼 보이는 것을 기대하기 때문에 이제는 조롱 한 것을 사용하여 시험에서 행동을 강제 할 수 있습니다. 다음은 JUnit 테스트의 예입니다.
@Test
public void testFirstSwitchStatement() {
    MyClass mc = new MyClass();
    IRandomWrapper random = new MockedRandomWrapper(0);
    mc.setRandomWrapper(random);
    mc.doSomething();
    // verify the behaviour for when random spits out zero
}
@Test
public void testFirstSwitchStatement() {
    MyClass mc = new MyClass();
    IRandomWrapper random = new MockedRandomWrapper(1);
    mc.setRandomWrapper(random);
    mc.doSomething();
    // verify the behaviour for when random spits out one
}
도움이 되었기를 바랍니다.
답변
임의 생성 코드를 클래스 또는 메소드로 랩핑 한 다음 테스트 중에이를 모의 / 재정 의하여 원하는 값을 설정하여 테스트를 예측할 수 있습니다.
답변
지정된 범위 (0-10)와 지정된 세분성 (정수)이 있습니다. 따라서 테스트 할 때 임의의 숫자로 테스트하지 않습니다. 각 사례에 차례로 맞는 루프 내에서 테스트합니다. case 문을 포함하는 하위 함수에 난수를 전달하면 하위 함수를 테스트 할 수 있습니다.
답변
PowerMock 라이브러리를 사용하여 Random 클래스를 조롱하고 nextInt () 메소드를 스텁하여 예상 값을 리턴 할 수 있습니다. 원하지 않는 경우 원래 코드를 변경할 필요가 없습니다.
PowerMockito를 사용하고 있으며 비슷한 방법을 테스트했습니다. JUnit 테스트를 게시 한 코드는 다음과 같아야합니다.
@RunWith(PowerMockRunner.class)
@PrepareForTest( { Random.class, ClassUsingRandom.class } ) // Don't forget to prepare the Random class! :)
public void ClassUsingRandomTest() {
    ClassUsingRandom cur;
    Random mockedRandom;
    @Before
    public void setUp() throws Exception {
        mockedRandom = PowerMockito.mock(Random.class);
        // Replaces the construction of the Random instance in your code with the mock.
        PowerMockito.whenNew(Random.class).withNoArguments().thenReturn(mockedRandom);
        cur = new ClassUsingRandom();
    }
    @Test
    public void testSwitchAtZero() {
        PowerMockito.doReturn(0).when(mockedRandom).nextInt(10);
        cur.doSomething();
        // Verify behaviour at case 0
     }
    @Test
    public void testSwitchAtOne() {
        PowerMockito.doReturn(1).when(mockedRandom).nextInt(10);
        cur.doSomething();
        // Verify behaviour at case 1
     }
    (...)
스위치에서 사례를 더 추가하려는 경우 다음 매개 변수를 수신하기 위해 nextInt (int) 호출을 스텁 할 수도 있습니다.
PowerMockito.doReturn(0).when(mockedRandom).nextInt(Mockito.anyInt());
예쁘지 않나요? 🙂
답변
QuickCheck를 사용하십시오 ! 나는 최근에 이것을 가지고 놀기 시작했고 놀랍습니다. 대부분의 멋진 아이디어와 마찬가지로 Haskell에서 나온 것이지만 기본 아이디어는 미리 준비된 테스트 케이스를 제공하는 대신 난수 생성기가 대신 빌드 할 수 있다는 것입니다. 그렇게하면 xUnit에서 나타날 수있는 4-6 개의 경우 대신 컴퓨터에서 수백 또는 수천 개의 입력을 시도하고 설정 한 규칙에 맞지 않는 입력을 확인할 수 있습니다.
또한 QuickCheck는 실패 사례를 발견 할 때 실패하여 가장 간단한 사례를 찾을 수 있도록 단순화하려고 시도합니다. (물론 실패한 사례를 찾으면 xUnit 테스트로 빌드 할 수도 있습니다)
Java에는 두 가지 이상의 버전이 있으므로 문제가 없어야합니다.