Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Se sua automação de teste depende da presença de dispositivos ou recursos de teste, consulte o exemplo, TestResourceExample, e acompanhe como aproveitar o suporte a dispositivos ou recursos de teste disponíveis no TAEF. Certifique-se de que está familiarizado com a criação de testes básicos utilizando o TAEF e a execução básica do TAEF antes de prosseguir.
Criação para suporte a dispositivos - Arquivo de códigos-fonte
Te.Common.lib é necessária, além de outras bibliotecas necessárias para autorar um teste no TAEF.
Autoria para suporte a dispositivos - Definição de recursos de teste
Os usuários são responsáveis por criar sua própria definição de recurso de teste (dispositivo). Para fazer isso, você precisa implementar ITestResource. ITestResource é definido no arquivo de cabeçalho publicado ITestResource.h e tem a seguinte aparência:
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*/
Em nosso exemplo, a classe MyTestResource implementa ITestResource COM Interface. Em ITestResource.h, você também encontrará uma lista de propriedades "must-have" definidas. Deve ser possível obter o GUID para o recurso de teste usando GetGuid(..) e o Name, Id e Type do recurso usando GetValue(...). Se alguma dessas informações estiver faltando em um TestResource, a TAEF considerará que ela é inválida e não manterá suas informações. (Consulte a seção "Construindo a lista de recursos" a seguir).
Criação para suporte a dispositivos - Especificando metadados dependentes de recursos
Para especificar que o módulo de teste tem métodos de teste dependentes de recursos de teste, uma propriedade de metadados de nível de módulo 'TestResourceDependent' deve ser definida como "true". A propriedade é herdada por todas as classes no módulo de teste e por todos os métodos de teste nessas classes. Se qualquer um dos métodos de teste no módulo não for dependente de recursos de teste, ele deverá redefinir explicitamente o valor de metadados como false. Todos os outros métodos de teste que dependem do recurso de teste devem fornecer uma consulta de seleção usando "Id" e/ou "Type" do recurso de teste.
Aqui estão alguns exemplos rápidos de "ResourceSelection" para nossa lista de recursos de exemplo e o que cada um deles implica:
- "@Id='HD*'": corresponde a cada recurso com um Id que começa com "HD"
- "@Type='PCI'": corresponde a cada recurso do Tipo "PCI"
- "@Id='PCI*' OU @Id='HD*'": corresponde a cada recurso começando com "PCI" ou começando com "HD"
- "@Type='PCI' e @id='*37'": corresponde a cada recurso um do tipo "PCI" com um nome terminado em "37"
Em nosso código de exemplo, isso tem a seguinte aparência:
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()
...
};
No exemplo acima, você verá que o módulo está marcado como "TestResourceDependent". O NoTestResourceTest é explicitamente marcado como não dependente de nenhum recurso de teste definindo metadados "TestRssourceDependent" como "false". Todos os outros métodos de teste especificam um critério de seleção para os recursos de teste para os quais estão interessados em executar.
A gramática dos critérios de seleção é muito semelhante à gramática de consulta da interface de linha de comando disponível no TAEF. No caso de seleção de recursos, no entanto, ela é restrita ao uso de IDs e tipos de recursos. Como o ID do recurso é uma String, ele precisa ser colocado entre aspas simples. Você pode usar os caracteres curinga "*" ou "?" na especificação do valor Id. No nosso exemplo acima, no OneHDAudioTest, a seleção de recursos especifica uma correspondência para qualquer recurso em que Id começa com 'HD'. Da mesma forma, no caso do HDorPCITest, a seleção de recursos corresponderá a qualquer recurso em que o Id comece com 'HD' ou comece com 'PCI'. É importante notar que a seleção de recursos não diferencia maiúsculas de minúsculas - ou seja, 'pci', 'Pci' e 'PCI' serão todos tratados da mesma forma.
Com base na seleção de recursos, o TAEF invocará novamente o método de teste juntamente com os métodos de configuração e limpeza de nível de teste (se forem especificados) uma vez para cada recurso de teste que corresponda à seleção. As seções a seguir examinarão os detalhes sobre como especificar a lista de recursos e fornecê-la ao TAEF e como o método de teste pode recuperar os recursos na próxima seção.
Autorando para suporte a dispositivos - Construindo a lista de recursos
Assim que o TAEF encontrar um módulo de teste TestResourceDependente, ele procurará e invocará o método DLL-exportado BuildResourceList. É na implementação de BuildResourceList onde os usuários podem criar novos recursos de teste e adicioná-los à interface que é passada como um parâmetro para BuildResourceList. Vamos dar uma olhada na implementação deste método em nosso exemplo:
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 aceita uma referência a WEX::TestExecution::ResourceList como parâmetro. ResourceList é definido no arquivo de cabeçalho publicado ResourceList.h. Usando o método Add(...) na ResourceList, os usuários podem adicionar todos os recursos de teste descobertos ou criados para o TAEF gerenciar e trabalhar. O exemplo acima adicionou 5 desses recursos de teste.
O método Add falhará se o recurso de teste a ser adicionado não retornar o "Name", "Id", "Type" ou GUID para o recurso.
ResourceList será mantido durante o tempo de vida do módulo de teste - ou seja, até que todos os métodos de teste e métodos de limpeza sejam concluídos. Se BuildResourceList retornar um valor FAILED HRESULT, todos os métodos de teste dependentes de recursos no módulo de teste serão registrados como bloqueados sem execução. Todos os recursos que não sejam de teste serão executados independentemente disso.
BuildResourceList é invocado antes de quaisquer outros métodos no módulo de teste. Depois que a lista de recursos é criada (em BuildResourceList), os metadados "ResourceSelection" são usados para corresponder aos recursos disponíveis na lista de recursos. Se uma correspondência for encontrada, todos os métodos de configuração (módulo, classe, ordem de teste) serão invocados seguidos pelo próprio método de teste. O método de limpeza do nível de teste é chamado após cada invocação de teste.
Nos bastidores, o TAEF mantém a ResourceList na qual a seleção de recursos é aplicada. Por exemplo, para o método de teste OneHDAudioTest, os recursos de teste com Ids "HDAudio-deviceid-1" e "HDAudio-deviceid-2" corresponderão a 'HD*' e, para cada um deles, o método de teste será invocado novamente pelo TAEF (uma vez para cada). Haverá também um índice implícito associado a cada invocação do teste. Portanto, você verá <o qualificador>de namespace OneHDAudioTest#0 e <o qualificador>de namespace OneHDAudioTest#1 como as duas invocações.
Criação para suporte a dispositivos - Recuperando o dispositivo em um método de teste
As seções anteriores analisaram como adicionar os metadados necessários no nível de módulo, classe e método de teste. Eles também analisaram como definir recursos de teste personalizados e como adicioná-los à ResourceList na implementação de BuildResourceList. A próxima parte que se segue é recuperar os recursos no método de teste. Vamos dar uma olhada em um dos métodos de teste simples em nosso exemplo:
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 }
No OneHDAudioTest, a seleção de recursos seleciona um recurso de teste de cada vez em que o ID do recurso começa com 'HD'. A classe estática Resources definida em ResourceList.h fornece as APIs para recuperar a contagem, bem como o recurso real disponível durante qualquer invocação específica do teste. Nesse caso, como você pode ver nas linhas 4, 9 e 13 no exemplo acima, Resources::Count() fornece a contagem do número de recursos de teste disponíveis durante a invocação atual do método de teste. Neste método de ensaio, deve ser 1. Você pode verificar esse valor usando as macros VERIFY disponíveis no TAEF (Verify.h). Como você sabe, se qualquer uma das chamadas de verificação falhar em um teste TAEF baseado em exceção, a execução será encerrada nesse ponto e o método de teste será marcado como Falha.
Em seguida, usando Resources::Item(...) API e passando um índice no qual recuperar o recurso (neste caso, como apenas um recurso de teste estará disponível durante uma invocação, o índice sempre será 0), você pode recuperar o recurso de teste. O método de teste pode usar ainda mais o recurso de teste recuperado conforme necessário para seu teste.
O mesmo princípio básico é seguido em todos os métodos de ensaio. Dê uma olhada em outros métodos de teste no exemplo para obter uma melhor compreensão.
Executando um módulo de teste dependente de recursos de teste
Com os testes dependentes de recursos de teste já desenvolvidos, pode agora executá-los usando o TAEF. O ponto-chave a ser observado é que os testes TestResourceDependent só podem ser executados inproc. Isso significa que, mesmo que você não especifique explicitamente a opção "/inproc", ela será adicionada assim que o TAEF descobrir o módulo de teste dependente de recursos de teste. Como você deve saber, testes de apenas um módulo de teste podem ser executados em uma determinada execução TAEF quando a opção "/inproc" está presente. Isso significa que você não pode especificar mais de um módulo de teste na linha de comando se o módulo de teste depender de recursos.
Para realmente executar todos os testes em nosso módulo de teste, você pode simplesmente executar:
te Examples\Cpp.TestResource.Example.dll
Uma maneira útil de obter apenas uma lista de todas as invocações de método de teste e as combinações de dados e metadados sem realmente executar os métodos de teste é usar a opção /listproperties na linha de comando. Vamos dar uma olhada na saída.
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 o índice implícito que é adicionado ao nome do método de teste durante cada invocação de um método de teste dependente de recursos de teste. A propriedade ResourceSelection é mostrada seguida por uma lista de todos os recursos que estarão disponíveis para o método de teste na ordem em que estarão disponíveis. Por exemplo, no caso da terceira invocação de HDAudioHDAudioPCITest (HDAudioHDAudioPCITest#2), HDAudio-deviceid-1 será o recurso disponível no índice 0 em Resources::Item(...).
Você pode ser mais específico sobre qual execução de teste lhe interessa usando a linguagem de consulta para seleção via linha de comandos disponível no TAEF. Por exemplo, para selecionar todas as invocações de métodos de teste onde os recursos de teste 'PCI-deviceid-3' estão disponíveis, você pode usar os critérios de seleção:
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
Da mesma forma, para selecionar um método de teste específico pelo nome (observe que os nomes do método de teste são totalmente qualificados junto com o índice de invocação anexado no final), você pode usar uma consulta de seleção da seguinte maneira:
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 o aviso implícito de inproc adicionado na terceira linha do exemplo acima. A consulta de seleção acima teve o mesmo efeito que a consulta de seleção:/select:"@Name='*OneHDAudio*' And @Resource:Index=1". Também é possível selecionar um recurso usando seu Nome ou Tipo (ou Id, como mostrado acima). Por exemplo, /select:"@Name='*PCIHDAudioTest*' e @Resource:Name='PCI3'" selecionará os métodos de teste PCIHDAudioTest#4 e PCIHDAudioTest#5.
Experimentar essas e outras consultas de seleção no prompt de comando é deixado como um exercício para o leitor.