[이 게시물은 다음에도 표시됩니다. Dustin의 깃허브 블로그].
최근에 Membase 사용자가 바람직하지 않은 상태를 초래한 일련의 연산을 지적할 수 있습니다. 제가 작성한 정말 좋은 엔진 테스트가 많지만, 다음과 같은 경우는 그렇지 않습니다. 이 케이스:
이 버그는 매우 간단합니다. 만료가 게으르고 이 경우 만료 확인을 하지 않는 것으로 밝혀졌습니다. 아주 쉽게
이 테스트를 작성하면서 바로 생각하게 된 것은 기타 케이스가 실행되고 있지 않았습니다.
테스트에 도움이 되는 도구는 무수히 많다는 것을 알고 있습니다. 저도 하나 만들었습니다. 필요한 모든 테스트를 작성하고 실행하는 프레임워크를 작성하는 데 한 시간 정도 걸렸을 겁니다. 여기서 설명하는 것과는 다른 점이 있습니다, 빠른 확인 환경이 특정 상태가 될 것으로 예상하고 환경을 다른 상태로 만드는 동작을 표현하는 매우 간단한 무언가를 원한다는 것입니다. 그런 다음 이러한 동작이 예상치 못한 방식으로 서로 간섭하지 않도록 가능한 모든 배열을 치고 싶습니다.

특히 다음과 같은 테스트 시퀀스에 대해 생성되는 테스트 수가 매우 빠르게 증가합니다. n 의 작업 a 가능한 작업은 대략 다음과 같습니다. an.
세 가지 정의된 동작이 두 가지 시퀀스로 순열되어 있다고 가정해 보겠습니다. 그러면 오른쪽 다이어그램에 표시된 것처럼 9개의 가능성으로 확장됩니다.
다이어그램의 동작은 단일 키에 대한 멤캐시드 시맨틱으로 정의되어 있으므로 추가 항목이 하지 않아야 합니다 존재하고 del 항목이 필수 존재합니다.
생성된 테스트는 각 흰색 상자에서 성공을, 각 빨간색 상자에서 실패를 예상하고 예상되는 상태 변이를 추적하여 어설션을 구축합니다.

첫 번째 테스트는... 음, 테스트 실행은 11 의 순서로 작업을 수행합니다. 4 작업. 앞으로 할 작업이 더 있지만 4 의 길이가 꽤 길기 때문에 왼쪽 차트를 통해 제 성장률을 확인할 수 있습니다.
멋진 부분은 원래의 버그를 아주 쉽게 지적하고 다른 몇 가지 버그를 제한적인 노력으로 지적했다는 것입니다.
어떻게 사용하나요?

API는 지금까지 매우 간단하고 구성하기 쉽습니다. 기본적으로 5개의 클래스가 있습니다(오른쪽 이미지에 3개가 표시되어 있습니다).
조건
A 조건 는 전제 조건과 후제 조건에 사용되는 간단한 콜러블입니다. 주어진 클래스는 어느 쪽에 사용되든 상관하지 않으며, 많은 경우 두 가지 모두에 사용됩니다.
예를 들어, 제가 구현한 DoesNotExist:
def __call__(self, 상태):
반환 테스트키 not in 상태
효과
An 효과 는 상태에 대한 우리의 시각을 변화시킵니다(드라이버에 따라 실제로 세상의 무언가가 함께 변화할 수도 있습니다). 예를 들어 스토어 효과 는 다음과 같이 작동합니다:
def __call__(self, 상태):
상태[테스트키] = ‘0’
액션
An 액션 는 효과 및 하나 이상의 조건 클래스를 사전 및 사후 조건으로 지정할 수 있습니다. 예를 들어, 두 가지 액션을 살펴보겠습니다. 추가 액션과 설정 액션:
클래스 Set(Action):
effect = StoreEffect()
postconditions = [Exists()]
클래스 추가(액션):
전제 조건 = [DoesNotExist()]
effect = StoreEffect()
postconditions = [Exists()]
여기서 흥미로운 부분은 설정과 추가의 의미는 다르지만 동일한 조건과 효과의 다른 구성으로 표현된다는 점입니다.
드라이버
드라이버가 더 큰 부분을 차지합니다(정의된 메서드가 7개!). 멤캐시드 엔진용 C 테스트 스위트를 생성하는 것부터 원격 프로토콜에서 실제로 테스트를 실행하는 것까지 모든 작업을 수행할 수 있을 만큼 충분한 기능을 갖추고 있습니다.
전체 내용은 문서에 설명되어 있으므로 여기서는 설명하지 않겠습니다. 출처. 그러나 처음에 찾지 못한 오류를 보여주는 몇 가지 예제 코드를 보여드리면서 이 글을 마무리하겠습니다:
ENGINE_HANDLE_V1 *h1) {
추가(h, h1);
assertHasNoError(); // 값 는 “0”
추가(h, h1);
assertHasError(); // 값 는 “0”
지연(만료+<span 클래스="mi">1);
assertHasNoError(); // 값 는 not 정의
추가(h, h1);
assertHasNoError(); // 값 는 “0”
체크값(h, h1, “0”);
반환 성공;
}
</span>
이는 각 단계에서 얼마나 많은 정보를 알고 있는지 보여줍니다. 여기에서 스텁으로 모든 종류의 작업을 수행할 수 있습니다(예를 들어 위의 지연은 memcached testapp "시간 여행" 기능으로 구현되었습니다).
여기부터는 덜 흥미롭습니다. 우리는 제약 조건을 제공하고, 테스트를 작성하며, 사용자가 이전에 보지 못했던 또 다른 영역이 있는지 확인합니다.