Поделиться через


Интернета вещей и Edge

Если автоматизация тестирования зависит от наличия устройств или тестовых ресурсов, обратитесь к примеру 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 реализует COM-интерфейс ITestResource. В ITestResource.h вы также найдете список определенных свойств "must-have". Необходимо получить GUID для тестового ресурса с помощью GetGuid(.) и имени, идентификатора и типа ресурса с помощью GetValue(...). Если какая-либо из них отсутствует в TestResource, TAEF будет считаться недопустимым и не поддерживать его сведения. (См. раздел "Создание списка ресурсов", приведенный ниже.

Разработка для поддержки устройств— указание метаданных, зависимых от ресурсов

Чтобы указать, что в тестовом модуле есть тестовые зависимые методы тестирования, свойство метаданных уровня модуля TestResourceDependent должно иметь значение true. Свойство наследуется всеми классами в тестовом модуле и всеми методами тестирования в этих классах. Если любой из методов теста в модуле не зависит от тестового ресурса, то он должен явно повторно задать значение false для значения метаданных. Все другие методы тестирования, зависящие от тестового ресурса, должны предоставить запрос выбора с помощью идентификатора тестового ресурса и /или типа.

Ниже приведены некоторые краткие примеры "ResourceSelection" для нашего примера списка ресурсов и то, что подразумевает каждый из них:

  • "@Id='HD*": соответствует каждому ресурсу с идентификатором, начиная с "HD"
  • "@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. Однако в случае выбора ресурсов он ограничен использованием идентификатора ресурса и типов. Так как идентификатор ресурса является строкой, он должен быть заключен в одинарные кавычки. Вы можете использовать дикие карта символы "*" или "?" в спецификации значения идентификатора. В приведенном выше примере в OneHDAudioTest выбор ресурса указывает соответствие любому ресурсу, где идентификатор начинается с hd. Аналогичным образом, в случае HDorPCITest выбор ресурса будет соответствовать любому ресурсу, где идентификатор начинается с 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. Используя метод Add(...) в ResourceList, пользователи могут добавлять все обнаруженные или созданные для TAEF ресурсы тестирования для управления и работы с ними. В приведенном выше примере добавлено 5 таких тестовых ресурсов.

Метод Add завершится ошибкой, если добавленный тестовый ресурс не возвращает значение Name, Id, Type или GUID ресурса.

ResourceList будет поддерживаться в течение всего времени существования тестового модуля, то есть до тех пор, пока все методы тестирования и методы очистки не будут выполнены. Если BuildResourceList возвращает значение FAILED HRESULT, все методы тестирования, зависящие от ресурсов, в модуле тестирования регистрируются как заблокированные без выполнения. Все не тестовые ресурсы будут выполняться независимо от этого.

BuildResourceList вызывается перед любыми другими методами в тестовом модуле. После построения списка ресурсов (в BuildResourceList) метаданные ResourceSelection используются для сопоставления доступных ресурсов в списке ресурсов. При обнаружении совпадения вызываются все методы установки (модуль, класс, порядок тестирования) и сам метод тестирования. Метод очистки уровня теста вызывается после каждого вызова теста.

За кулисами TAEF сохраняет ResourceList, к которому применяется выбор ресурса. Например, для метода тестирования OneHDAudioTest тестовые ресурсы с идентификаторами HDAudio-deviceid-1 и HDAudio-deviceid-2 будут соответствовать как HD*, так и для каждого из них, метод тестирования будет повторно вызываться TAEF (один раз для каждого). Также будет неявный индекс, связанный с каждым вызовом теста. Таким образом, вы увидите <квалификатор>пространства имен OneHDAudioTest#0 и <квалификатор>пространства имен OneHDAudioTest#1 в качестве двух вызовов.

Разработка для поддержки устройств — извлечение устройства в методе тестирования

В предыдущих разделах описано, как добавить необходимые метаданные на уровне модуля, класса и метода тестирования. Они также рассмотрели, как определить пользовательские тестовые ресурсы и как добавить их в ResourceList в реализации BuildResourceList. Следующая часть — получение ресурсов в методе тестирования. Рассмотрим один из простых методов тестирования в нашем примере:

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 выбор ресурса выбирает один тестовый ресурс в то время, когда идентификатор ресурса начинается с hd. Ресурсы статического класса, определенные в ResourceList.h, предоставляют API-интерфейсы для получения количества, а также фактического ресурса, доступного во время любого заданного вызова теста. В этом случае, как можно увидеть в строках 4, 9 и 13 в приведенном выше примере, Resources::Count() дает количество тестовых ресурсов, доступных во время текущего вызова метода теста. В этом методе теста это должно быть 1. Это значение можно проверить с помощью макросов VERIFY, доступных в TAEF (Verify.h). Как вы знаете, если любой из вызовов проверки завершается сбоем в тесте TAEF на основе исключений, выполнение завершится в этом моменте, и метод теста будет помечен как сбой.

Далее с помощью resources::Item(...) API и передача индекса, по которому требуется получить ресурс (в этом случае во время вызова будет доступен только один тестовый ресурс, индекс всегда будет 0), можно получить тестовый ресурс. Метод теста может дополнительно использовать полученный тестовый ресурс, так как он нуждается в тестировании.

Один и тот же базовый принцип следует во всех методах тестирования. Ознакомьтесь с другими методами тестирования в примере, чтобы получить лучшее представление.

Выполнение тестового модуля, зависяющего от ресурсов

Теперь с помощью тестов, зависимых от ресурсов, созданных и созданных тестов, его можно выполнить с помощью TAEF. Ключевой моментом является то, что тесты TestResourceDependent могут выполняться только в формате inproc. Это означает, что даже если вы явно не укажете параметр "/inproc" , он будет добавлен, как только TAEF обнаруживает тестовый модуль, зависимый от тестового ресурса. Как вы знаете, тесты из одного тестового модуля можно выполнять в заданном выполнении TAEF при наличии переключателя "/inproc". Это означает, что в командной строке не удается указать несколько тестового модуля, если тестовый модуль зависит от ресурсов.

Чтобы выполнить все тесты в модуле тестирования, можно просто выполнить:

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 будет ресурсом, доступным по индексу 0 в Resources::Item(...).

Чтобы узнать больше о том, какой тестовый вызов вас интересует, можно использовать язык запросов выбора командной строки, доступный в 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

Обратите внимание на неявное предупреждение, добавленное в третьей строке приведенного выше примера. Приведенный выше запрос выбора имел тот же эффект, что и запрос выбора:/select:"@Name='*OneHDAudio*" и @Resource:Index=1". Также можно выбрать ресурс с помощью имени или типа (или идентификатора, как показано выше). Например, /select:"@Name='*PCIHDAudioTest*" и @Resource:Name=PCI3" будут выбирать методы тестирования PCIHDAudioTest#4 и PCIHDAudioTest#5.

Попробуйте выполнить эти и другие запросы выбора в командной строке в качестве упражнения для читателя.