다음을 통해 공유


디바이스 지원

테스트 자동화가 디바이스 또는 테스트 리소스의 존재에 의존하는 경우 예제인 TestResourceExample을 참조하고 TAEF에서 사용할 수 있는 디바이스 지원 또는 테스트 리소스 지원을 활용하는 방법을 따릅니다. 계속하기 전에 TAEF 및 TAEF의 기본 실행을 사용하여 기본 테스트를 작성하는 방법을 잘 알고 있는지 확인하세요.

디바이스 지원 작성 - 원본 파일

Te.Common.lib는 TAEF에서 테스트를 작성하는 데 필요한 다른 라이브러리 외에도 필요합니다.

디바이스 지원을 위한 작성 - 리소스 정의 테스트

사용자는 자신의 테스트 리소스(디바이스) 정의를 만들 책임이 있습니다. 이렇게 하려면 ITestResource를 구현해야 합니다. ITestResource는 게시된 헤더 파일 ITestResource.h에 정의되며 다음과 같이 표시됩니다.

namespace WEX { namespace TestExecution
{
    namespace TestResourceProperty
    {
        // the following are reserved and must have properties for any TestResource definition
        static const wchar_t c_szName[] = L"Name";
        static const wchar_t c_szId[] = L"Id";
        static const wchar_t c_szGuid[] = L"GUID";
        static const wchar_t c_szType[] = L"Type";
    }

    struct __declspec(novtable) __declspec(uuid("79098e4c-b78d-434b-854d-2b59f5c4acc5")) ITestResource : public IUnknown
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetGuid(GUID* pGuid) = 0;
        virtual HRESULT STDMETHODCALLTYPE SetGuid(GUID guid) = 0;
        virtual HRESULT STDMETHODCALLTYPE GetValue(BSTR name, BSTR* pValue) = 0;
        virtual HRESULT STDMETHODCALLTYPE SetValue(BSTR name, BSTR value) = 0;
    };
} /*namespace TestExecution*/ } /*namespace WEX*/

이 예제에서 MyTestResource 클래스는 ITestResource COM 인터페이스를 구현합니다. ITestResource.h에서 정의된 "필수" 속성 목록도 찾을 수 있습니다. GetGuid(..) 및 GetValue(...)를 사용하여 리소스의 이름, ID 및 형식을 사용하여 테스트 리소스에 대한 GUID를 가져올 수 있어야 합니다. TestResource에 누락된 항목이 있으면 TAEF는 잘못된 것으로 간주하고 해당 정보를 유지 관리하지 않습니다. (다음에 나와 있는 "리소스 목록 빌드" 섹션을 참조하세요).

디바이스 지원 작성 - 리소스 종속 메타데이터 지정

테스트 모듈에 테스트 리소스 종속 테스트 메서드가 있는지 지정하려면 모듈 수준 메타데이터 속성 'TestResourceDependent' 를 "true"로 설정해야 합니다. 이 속성은 테스트 모듈의 모든 클래스와 이러한 클래스의 모든 테스트 메서드에 의해 상속됩니다. 모듈의 테스트 메서드 중 하나라도 테스트 리소스에 종속되어 있지 않으면 메타데이터 값을 false로 명시적으로 다시 설정해야 합니다. 테스트 리소스에 의존하는 다른 모든 테스트 메서드는 테스트 리소스의 "ID" 및/또는 "형식"을 사용하여 선택 쿼리를 제공해야 합니다.

다음은 예제 리소스 목록에 대한 몇 가지 빠른 샘플 "ResourceSelection"과 각 리소스 목록의 의미입니다.

  • "@Id='HD*'": 각 리소스를 "HD"로 시작하는 ID와 일치
  • "@Type='PCI'": "PCI" 형식의 각 리소스와 일치합니다.
  • "@Id='PCI*' 또는 @Id='HD*'": "PCI"로 시작하거나 "HD"로 시작하는 각 리소스와 일치합니다.
  • "@Type='PCI' 및 @id='*37'": "PCI" 형식의 각 리소스를 "37"로 끝나는 이름과 일치합니다.

예제 코드에서는 다음과 같이 표시됩니다.

BEGIN_MODULE()
    MODULE_PROPERTY(L"TestResourceDependent", L"true")
END_MODULE()

    class TestResourceExample
    {
        TEST_CLASS(TestResourceExample);

        BEGIN_TEST_METHOD(NoTestResourceTest)
            TEST_METHOD_PROPERTY(L"TestResourceDependent", L"false")
        END_TEST_METHOD()

        BEGIN_TEST_METHOD(OneHDAudioTest)
            TEST_METHOD_PROPERTY(L"ResourceSelection", L"@Id='HD*'")
        END_TEST_METHOD()

        ...

        BEGIN_TEST_METHOD(HDorPCITest)
            TEST_METHOD_PROPERTY(L"ResourceSelection", L"@Id='PCI*' OR @Id='HD*'")
        END_TEST_METHOD()
        ...
    };

위의 예제에서는 모듈이 "TestResourceDependent"로 표시된 것을 볼 수 있습니다. NoTestResourceTest는 "TestRssourceDependent" 메타데이터를 "false"로 설정하여 테스트 리소스에 종속되지 않은 것으로 명시적으로 표시됩니다. 다른 모든 테스트 메서드는 실행하려는 테스트 리소스에 대한 선택 조건을 지정합니다.

선택 조건 문법은 TAEF에 사용할 수 있는 명령줄 선택 쿼리 문법과 매우 유사합니다. 그러나 리소스 선택의 경우 리소스 ID 및 형식의 사용으로 제한됩니다. 리소스 ID는 String이므로 작은따옴표로 묶어야 합니다. ID 값의 사양에서 와일드카드 문자 "*" 또는 "?"를 사용할 수 있습니다. 위의 예제에서 OneHDAudioTest에서 리소스 선택은 ID가 'HD'로 시작하는 모든 리소스와 일치하도록 지정합니다. 마찬가지로 HDorPCITest의 경우 리소스 선택은 ID가 'HD'로 시작하거나 'PCI'로 시작하는 모든 리소스와 일치합니다. 리소스 선택은 대/소문자를 구분하지 않는다는 점에 유의해야 합니다. 즉, 'pci', 'Pci' 및 'PCI'는 모두 동일하게 처리됩니다.

리소스 선택에 따라 TAEF는 선택 영역과 일치하는 각 테스트 리소스에 대해 테스트 수준 설정 및 정리 메서드(지정된 경우)와 함께 테스트 메서드를 다시 호출합니다. 다음 섹션에서는 리소스 목록을 지정하고 TAEF에 제공하는 방법과 테스트 메서드가 다음 섹션에서 리소스를 검색하는 방법에 대한 세부 정보를 검토합니다.

디바이스 지원 작성 - 리소스 목록 빌드

TAEF가 TestResourceDependent 테스트 모듈을 발견하면 dll에서 내보낸 메서드 BuildResourceList를 찾고 호출합니다. 사용자가 새 테스트 리소스를 만들고 BuildResourceList에 매개 변수로 전달되는 인터페이스에 추가할 수 있는 BuildResourceList 구현에 있습니다. 예제에서 이 메서드의 구현을 살펴보겠습니다.

using namespace WEX::TestExecution;
HRESULT __cdecl BuildResourceList(ResourceList& resourceList)
{
    Log::Comment(L"In BuildResourceList");

    GUID myGuid;
    VERIFY_SUCCEEDED(::CoCreateGuid(&myGuid));

    CComPtr<ITestResource> spTestResource;
    spTestResource.Attach(new MyTestResource(L"HDAudio1", L"HDAudio-deviceid-1", myGuid, L"HD"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"HDAudio2", L"HDAudio-deviceid-2", myGuid, L"HD"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI1", L"PCI-deviceid-1", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI2", L"PCI-deviceid-2", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    spTestResource.Attach(new MyTestResource(L"PCI3", L"PCI-deviceid-3", myGuid, L"PCI"));
    resourceList.Add(spTestResource);

    return S_OK;
}

BuildResourceList는 WEX::TestExecution::ResourceList에 대한 참조를 해당 매개 변수로 허용합니다. ResourceList는 게시된 헤더 파일 ResourceList.h에 정의됩니다. ResourceList에서 Add(...) 메서드를 사용하여 사용자는 TAEF가 관리하고 작업할 수 있도록 검색되거나 생성된 모든 테스트 리소스를 추가할 수 있습니다. 위의 예제에서는 이러한 5개의 테스트 리소스를 추가했습니다.

추가할 테스트 리소스가 리소스에 대한 "이름", "ID", "형식" 또는 GUID를 반환하지 못하면 Add 메서드가 실패합니다.

ResourceList는 테스트 모듈의 수명 동안 유지 관리됩니다. 즉, 모든 테스트 메서드 및 정리 메서드 실행이 완료될 때까지 유지됩니다. BuildResourceList가 FAILED HRESULT 값을 반환하는 경우 테스트 모듈의 모든 리소스 종속 테스트 메서드는 실행하지 않고 차단된 것으로 기록됩니다. 테스트가 아닌 모든 리소스는 관계없이 실행됩니다.

BuildResourceList는 테스트 모듈의 다른 메서드 앞에 호출됩니다. BuildResourceList에서 리소스 목록을 빌드한 후에는 "ResourceSelection" 메타데이터를 사용하여 리소스 목록에서 사용 가능한 리소스를 일치시킬 수 있습니다. 일치 항목이 발견되면 모든 설정 메서드(모듈, 클래스, 테스트 순서)가 호출되고 테스트 메서드 자체가 호출됩니다. 테스트 수준 정리 메서드는 각 테스트 호출 후에 호출됩니다.

백그라운드에서 TAEF는 리소스 선택이 적용되는 ResourceList를 유지합니다. 예를 들어 OneHDAudioTest 테스트 메서드의 경우 ID가 "HDAudio-deviceid-1" 및 "HDAudio-deviceid-2"인 테스트 리소스는 모두 'HD*'와 일치하며 각 테스트 메서드는 TAEF에서 다시 호출됩니다(각각 1회). 또한 테스트의 각 호출과 연결된 암시적 인덱스도 있습니다. 따라서 네임스페이 <스 한정>자 OneHDAudioTest#0 및 <네임스페이스 한정자>OneHDAudioTest#1이 두 개의 호출로 표시됩니다.

디바이스 지원 작성 - 테스트 메서드에서 디바이스 검색

이전 섹션에서는 모듈, 클래스 및 테스트 메서드 수준에서 필요한 메타데이터를 추가하는 방법을 살펴보았습니다. 또한 사용자 지정 테스트 리소스를 정의하는 방법과 BuildResourceList 구현에서 ResourceList에 추가하는 방법을 살펴보았습니다. 다음 부분은 테스트 메서드에서 리소스를 검색하는 것입니다. 예제에서 간단한 테스트 방법 중 하나를 살펴보겠습니다.

1   void TestResourceExample::OneHDAudioTest()
2   {
3       Log::Comment(L"In HD audio test");
4       size_t count = Resources::Count();
5       size_t index = 0;
6       VERIFY_ARE_EQUAL(count, (index + 1));
7
8       CComPtr<ITestResource> spTestResource;
9       VERIFY_SUCCEEDED(Resources::Item(index, &spTestResource));
10
11      // Get Resource Id
12      CComBSTR value;
13      VERIFY_SUCCEEDED(spTestResource->GetValue(CComBSTR(TestResourceProperty::c_szId), &value));
14      Log::Comment(L"Resource Id is " + String(value));
15  }

OneHDAudioTest에서 리소스 선택은 리소스 ID가 'HD'로 시작하는 한 번에 하나의 테스트 리소스를 선택합니다. ResourceList.h에 정의된 정적 클래스 리소스는 테스트를 호출하는 동안 사용할 수 있는 실제 리소스뿐만 아니라 개수를 검색하기 위한 API를 제공합니다. 이 경우 위의 예제에서 4, 9 및 13줄에서 볼 수 있듯이 Resources::Count()는 테스트 메서드를 현재 호출하는 동안 사용할 수 있는 테스트 리소스 수를 제공합니다. 이 테스트 메서드에서는 1이어야 합니다. TAEF(Verify.h)에서 사용할 수 있는 VERIFY 매크로를 사용하여 이 값을 확인할 수 있습니다. 아시다시피 예외 기반 TAEF 테스트에서 확인 호출이 실패하면 해당 지점에서 실행이 종료되고 테스트 메서드가 실패로 표시됩니다.

다음으로, Resources::Item(...) 사용 API 및 리소스를 검색할 인덱스 전달(이 경우 호출 중에 하나의 테스트 리소스만 사용할 수 있으므로 인덱스가 항상 0이기 때문에) 테스트 리소스를 검색할 수 있습니다. 테스트 메서드는 검색된 테스트 리소스를 테스트에 필요한 대로 추가로 사용할 수 있습니다.

모든 테스트 메서드에서 동일한 기본 원칙을 따릅니다. 더 잘 이해하려면 예제의 다른 테스트 메서드를 살펴보세요.

테스트 리소스 종속 테스트 모듈 실행

이제 테스트 리소스 종속 테스트가 작성되고 빌드되었으므로 이제 TAEF를 사용하여 테스트 리소스 종속 테스트를 실행할 수 있습니다. 주의해야 할 핵심은 TestResourceDependent 테스트는 inproc만 실행할 수 있다는 것입니다. 즉, "/inproc" 스위치를 명시적으로 지정하지 않더라도 TAEF가 테스트 리소스 종속 테스트 모듈을 검색하는 즉시 추가됩니다. 아시다시피 , "/inproc" 스위치가 있을 때 한 테스트 모듈의 테스트만 지정된 TAEF 실행에서 실행할 수 있습니다. 즉, 테스트 모듈이 리소스에 종속된 경우 명령줄에서 둘 이상의 테스트 모듈을 지정할 수 없습니다.

테스트 모듈에서 모든 테스트를 실제로 실행하려면 다음을 실행하기만 하면 됩니다.

te Examples\Cpp.TestResource.Example.dll

실제로 테스트 메서드를 실행하지 않고 모든 테스트 메서드 호출 및 데이터 및 메타데이터 조합 목록을 가져오는 유용한 방법은 명령줄에서 /listproperties 스위치를 사용하는 것입니다. 출력을 살펴보겠습니다.

te Examples\Cpp.TestResource.Example.dll /listproperties

Test Authoring and Execution Framework v2.9.3k for x86
In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

        f:\toolsdev.binaries.x86chk\WexTest\CuE\TestExecution\Examples\Cpp.TestResource.Example.dll
                Property[TestResourceDependent] = true

            WEX::TestExecution::Examples::TestResourceExample
                WEX::TestExecution::Examples::TestResourceExample::NoTestResourceTest
                        Property[TestResourceDependent] = false

                WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#0
                        Property[ResourceSelection] = @Id='HD*' 
                
                            Resource#0
                                Id = HDAudio-deviceid-1
                                Name = HDAudio1
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1
                        Property[ResourceSelection] = @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-2
                                Name = HDAudio2
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#0
                        Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#1
                        Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-2
                                Name = PCI2
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#2
                         Property[ResourceSelection] = @Id='PCI*'
                        
                            Resource#0
                                Id = PCI-deviceid-3
                                Name = PCI3
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#0
                        Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-1
                                Name = HDAudio1
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#1
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = HDAudio-deviceid-2
                                Name = HDAudio2
                                Type = HD

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#2
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#3
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-2
                                Name = PCI2
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#4
                         Property[ResourceSelection] = @Id='PCI*' OR @Id='HD*'
                        
                            Resource#0
                                Id = PCI-deviceid-3
                                Name = PCI3
                                Type = PCI

                WEX::TestExecution::Examples::TestResourceExample::PCI1AudioTest #0
                         Property[ResourceSelection] = @Id='PCI*' AND @Id='*1'
                        
                            Resource#0
                                Id = PCI-deviceid-1
                                Name = PCI1
                                Type = PCI

테스트 리소스 depent 테스트 메서드를 호출할 때마다 테스트 메서드 이름에 추가되는 암시적 인덱스입니다. ResourceSelection 속성 뒤에 테스트 메서드에서 사용할 수 있는 모든 리소스 목록을 사용할 수 있는 순서대로 표시합니다. 예를 들어 HDAudioHDAudioPCITest(HDAudioHDAudioPCITest#2)의 세 번째 호출의 경우 HDAudio-deviceid-1은 Resources::Item(...)의 인덱스 0에서 사용할 수 있는 리소스입니다.

TAEF에서 사용할 수 있는 명령줄 선택 쿼리 언어를 사용하여 관심 있는 테스트 호출에 대해 더 구체적으로 지정할 수 있습니다. 예를 들어 테스트 리소스 'PCI-deviceid-3'을 사용할 수 있는 테스트 메서드의 모든 호출을 선택하려면 선택 조건을 사용할 수 있습니다.

te Examples\Cpp.TestResource.Example.dll /list
          /select:"@Resource:Id='PCI-deviceid-3'"

Test Authoring and Execution Framework v2.9.3k for x86
In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

        f: \Examples\Cpp.TestResource.Example.dll
            WEX::TestExecution::Examples::TestResourceExample
                WEX::TestExecution::Examples::TestResourceExample::OnePCIDeviceTest#2
                WEX::TestExecution::Examples::TestResourceExample::HDorPCITest#4

마찬가지로 이름으로 특정 테스트 메서드를 선택하려면(테스트 메서드 이름은 끝에 추가된 호출 인덱스와 함께 정규화됨) 다음과 같이 선택 쿼리를 사용할 수 있습니다.

te Examples\Cpp.TestResource.Example.dll /name:*OneHDAudioTest#1
Test Authoring and Execution Framework v2.2 Build 6.1.7689.0 (release.091218-1251) for x86

Discovered a test resource dependent test module. Assuming /InProc execution.

In BuildResourceList
Verify: SUCCEEDED(::CoCreateGuid(&myGuid))

StartGroup: WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1
In HD audio test
Verify: AreEqual(count, (index + 1))
Verify: SUCCEEDED(Resources::Item(index, &spTestResource))
Verify: SUCCEEDED(spTestResource->GetValue(CComBSTR(TestResourceProperty::c_szId), &value))
Resource Id is HDAudio-deviceid-2
WEX::TestExecution::Examples::TestResourceExample::OneHDAudioTest#1 [Passed]

Summary: Total=1, Passed=1, Failed=0, Blocked=0, Not Run=0, Skipped=0

위의 예제의 세 번째 줄에서 암시적 inproc 추가 경고를 확인합니다. 위의 선택 쿼리는 선택 쿼리:/select:"@Name='*OneHDAudio*' 및 "와 @Resource:Index=1같은 효과가 있었습니다. 이름 또는 형식(또는 위에 표시된 ID)을 사용하여 리소스를 선택할 수도 있습니다. 예를 들어 /select:"@Name='*PCIHDAudioTest*' 및 @Resource:Name='PCI3'는 테스트 메서드 PCIHDAudioTest#4 및 PCIHDAudioTest#5를 선택합니다.

명령 프롬프트에서 이러한 쿼리 및 기타 선택 쿼리를 사용해 보는 것은 판독기를 위한 연습으로 남아 있습니다.