Compartir a través de


Compatibilidad con dispositivos

Si la automatización de pruebas se basa en la presencia de dispositivos o recursos de prueba, consulte el ejemplo TestResourceExample y siga estos pasos sobre cómo aprovechar la compatibilidad con dispositivos o la compatibilidad con recursos de prueba disponibles en TAEF. Asegúrese de que está familiarizado con cómo crear pruebas básicas mediante TAEF y la ejecución básica de TAEF antes de continuar.

Creación para la compatibilidad con dispositivos: archivo de orígenes

Te.Common.lib es necesario además de otras bibliotecas necesarias para crear una prueba en TAEF.

Creación para la compatibilidad con dispositivos: definición de recursos de prueba

Los usuarios son responsables de crear su propia definición de recurso de prueba (dispositivo). Para ello, debe implementar ITestResource. ITestResource se define en el archivo de encabezado publicado ITestResource.h y tiene el siguiente aspecto:

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*/

En nuestro ejemplo, la clase MyTestResource implementa ITestResource COM Interface. En ITestResource.h, también encontrará una lista de propiedades "must-have" definidas. Debe ser posible obtener el GUID del recurso de prueba mediante GetGuid(..) y el nombre, el identificador y el tipo del recurso mediante GetValue(...). Si falta alguno de estos elementos en testResource, TAEF considera que no es válido y no lo mantiene. (Consulte la sección "Compilar la lista de recursos" que sigue).

Creación para la compatibilidad con dispositivos: especificación de metadatos dependientes del recurso

Para especificar que el módulo de prueba tiene métodos de prueba dependientes del recurso de prueba, una propiedad de metadatos de nivel de módulo 'TestResourceDependent' debe establecerse en "true". La propiedad se hereda por todas las clases del módulo de prueba y por todos los métodos de prueba de estas clases. Si alguno de los métodos de prueba del módulo no depende del recurso de prueba, debe volver a establecer explícitamente el valor de metadatos en false. Todos los demás métodos de prueba que dependen del recurso de prueba deben proporcionar una consulta de selección mediante el "Id" o "Type" del recurso de prueba.

Estos son algunos ejemplos rápidos de "ResourceSelection" para nuestra lista de recursos de ejemplo y lo que implica cada uno de ellos:

  • "@Id='HD*'": coincide con cada recurso cuyo identificador comience con "HD"
  • "@Type='PCI'": coincide con cada recurso de tipo "PCI"
  • "@Id='PCI*' O @Id='HD*'": coincide con cada recurso que comienza con "PCI" o que comienza con "HD"
  • "@Type='PCI' y @id='*37'": coincide con cada recurso de tipo "PCI" con un nombre que termina en "37".

En nuestro código de ejemplo, este aspecto es el siguiente:

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()
        ...
    };

En el ejemplo anterior, verá que el módulo está marcado como "TestResourceDependent". NoTestResourceTest se marca explícitamente como no depende de ningún recurso de prueba estableciendo los metadatos "TestRssourceDependent" en "false". Todos los demás métodos de prueba especifican un criterio de selección para los recursos de prueba que están interesados en ejecutar.

La gramática de criterios de selección es muy similar a la gramática de consulta de selección de línea de comandos disponible para TAEF. Sin embargo, en el caso de la selección de recursos, está restringido al uso de los identificadores de recursos y tipos. Dado que el identificador de recurso es una cadena, debe incluirse entre comillas simples. Puede usar los caracteres comodín "*" o "?" en la especificación del valor Id. En nuestro ejemplo anterior, en OneHDAudioTest, la selección de recursos especifica una coincidencia con cualquier recurso en el que id. comienza por "HD". Del mismo modo, en el caso de HDorPCITest, la selección de recursos coincidirá con cualquier recurso en el que id. comience por "HD" o comience por "PCI". Es importante tener en cuenta que la selección de recursos no distingue mayúsculas de minúsculas; es decir, "pci", "Pci" y "PCI" se tratarán igual.

En función de la selección de recursos, TAEF volverá a invocar el método de prueba junto con los métodos de configuración y limpieza del nivel de prueba (si se especifican) una vez para cada recurso de prueba que coincida con la selección. En las secciones siguientes se examinarán los detalles sobre cómo especificar la lista de recursos y proporcionarla a TAEF y cómo el método de prueba puede recuperar los recursos en la sección siguiente.

Desarrollo para la compatibilidad con dispositivos: elaboración de la lista de recursos

En cuanto TAEF encuentre un módulo de prueba TestResourceDependent, buscará e invocará el método exportado por dll BuildResourceList. Se encuentra en la implementación de BuildResourceList, donde los usuarios pueden crear nuevos recursos de prueba y agregarlos a la interfaz que se pasa como parámetro a BuildResourceList. Echemos un vistazo a la implementación de este método en nuestro ejemplo:

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 acepta una referencia a WEX::TestExecution::ResourceList como parámetro. ResourceList se define en el archivo de encabezado publicado ResourceList.h. Con el método Add(...) en ResourceList, los usuarios pueden agregar todos los recursos de prueba detectados o creados para QUE TAEF administre y trabaje con ellos. En el ejemplo anterior se agregaron 5 recursos de prueba.

Se producirá un error en el método Add si el recurso de prueba que se va a agregar no devuelve "Name", "Id", "Type" o GUID para el recurso.

ResourceList se mantendrá durante la vigencia del módulo de prueba, es decir, hasta que se ejecuten todos los métodos de prueba y los métodos de limpieza. Si BuildResourceList devuelve un valor HRESULT FAILED, todos los métodos de prueba dependientes del recurso del módulo de prueba se registran como bloqueados sin ejecutarse. Todos los recursos que no son de prueba se ejecutarán independientemente.

BuildResourceList se invoca antes de cualquier otro método del módulo de prueba. Después de compilar la lista de recursos (en BuildResourceList), los metadatos de "ResourceSelection" se usan para buscar coincidencias con los recursos disponibles en la lista de recursos. Si se encuentra una coincidencia, se invocan todos los métodos de instalación (módulo, clase, orden de prueba) seguidos del propio método de prueba. El método de limpieza del nivel de prueba se llama después de cada invocación de una prueba.

En segundo plano, TAEF conserva la lista de recursos en la que se aplica la selección de recursos. Por ejemplo, para el método de prueba OneHDAudioTest, los recursos de prueba con ids "HDAudio-deviceid-1" y "HDAudio-deviceid-2" coincidirán con "HD*" y para cada uno de ellos, el método de prueba se volverá a invocar mediante TAEF (una vez por cada uno). También habrá un índice implícito asociado a cada invocación de la prueba. Por lo tanto, verá <el calificador del espacio de nombres> OneHDAudioTest#0 y <el calificador del espacio de nombres> OneHDAudioTest#1 como las dos invocaciones.

Creación para la compatibilidad con dispositivos: recuperación del dispositivo en un método de prueba

En las secciones anteriores se ha analizado cómo agregar los metadatos necesarios en el nivel de módulo, clase y método de prueba. También observaron cómo definir recursos de prueba personalizados y cómo agregarlos a ResourceList en la implementación de BuildResourceList. La siguiente parte que sigue es la recuperación de los recursos en el método de prueba. Echemos un vistazo a uno de los métodos de prueba simples de nuestro ejemplo:

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  }

En OneHDAudioTest, la selección de recursos selecciona un recurso de prueba a la vez donde el identificador de recurso comienza por "HD". La clase estática Resources definida en ResourceList.h proporciona las API para recuperar el recuento, así como el recurso real disponible durante cualquier invocación dada de la prueba. En este caso, como puede ver en las líneas 4, 9 y 13 del ejemplo anterior, Resources::Count() proporciona el recuento del número de recursos de prueba disponibles durante la invocación actual del método de prueba. En este método de prueba, debe ser 1. Puede comprobar este valor mediante las macros VERIFY que están disponibles en TAEF (Verify.h). Como sabe, si alguna de las llamadas de comprobación produce un error en una prueba de TAEF basada en excepciones, la ejecución finalizará en ese momento y el método de prueba se marcará como Error.

A continuación, usando la API Resources::Item(...) y pasando un índice para recuperar el recurso (en este caso, dado que solo un recurso de prueba estará disponible durante una invocación, el índice siempre será 0), puedes recuperar el recurso de prueba. El método de prueba puede utilizar adicionalmente el recurso de prueba recuperado según lo necesite para sus pruebas.

Se sigue el mismo principio básico en todos los métodos de prueba. Eche un vistazo a otros métodos de prueba del ejemplo para comprender mejor.

Ejecución de un módulo de prueba dependiente de un recurso de prueba

Con las pruebas dependientes del recurso de prueba creadas y compiladas, ahora puede ejecutarlas mediante TAEF. El punto clave que se debe tener en cuenta es que las pruebas TestResourceDependent solo se pueden ejecutar enproc. Esto significa que incluso si no especifica explícitamente el modificador "/inproc", se agregará tan pronto como TAEF detecte el módulo de prueba dependiente del recurso de prueba. Como usted sabe, las pruebas de solo un módulo de prueba se pueden ejecutar en una sesión dada de TAEF cuando el modificador "/inproc" está presente. Esto significa que no puede especificar más de un módulo de prueba en la línea de comandos si el módulo de prueba depende del recurso.

Para ejecutar realmente todas las pruebas del módulo de prueba, puede ejecutar simplemente:

te Examples\Cpp.TestResource.Example.dll

Una manera útil de obtener una lista de todas las invocaciones del método de prueba y las combinaciones de datos y metadatos sin ejecutar realmente los métodos de prueba es usar el modificador /listproperties en la línea de comandos. Echemos un vistazo a la salida.

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

Observe el índice implícito que se agrega al nombre del método de prueba durante cada invocación de un método de prueba dependiente de un recurso de prueba. La propiedad ResourceSelection se muestra seguida de una lista de todos los recursos que estarán disponibles para el método de prueba en el orden en que estarán disponibles. Por ejemplo, en el caso de la tercera invocación de HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2), HDAudio-deviceid-1 será el recurso disponible en el índice 0 en Resources::Item(...).

Puede especificar más qué ejecución de prueba le interesa mediante el lenguaje de consulta de selección de línea de comandos disponible en TAEF. Por ejemplo, para seleccionar todas las invocaciones de métodos de prueba en las que los recursos de prueba "PCI-deviceid-3" están disponibles, puede usar los criterios de selección:

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

Del mismo modo, para seleccionar un método de prueba determinado por nombre (tenga en cuenta que los nombres de método de prueba están totalmente calificados junto con el índice de invocación añadido al final), puede usar una consulta de selección a continuación:

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

Observe la advertencia implícita inproc agregada en la tercera línea del ejemplo anterior. La consulta de selección anterior tuvo el mismo efecto que la consulta de selección:/select:"@Name='*OneHDAudio*' y @Resource:Index=1". También es posible seleccionar un recurso con su nombre o tipo (o id. como se muestra anteriormente). Por ejemplo, /select:"@Name='*PCIHDAudioTest*' y @Resource:Name='PCI3'" seleccionarán los métodos de prueba PCIHDAudioTest#4 y PCIHDAudioTest#5.

Probar estas y otras consultas de selección en el símbolo del sistema queda como ejercicio para el lector.