Compartilhar via


Fonte de dados PICT

Verifique se você está familiarizado com a execução básica do TAEF e saiba como criar testes usando-o antes de prosseguir com esta seção.

Antecedentes e Referências do PICT

PICT significa Teste Combinatório Independente por Pares. PICT permite que você especifique variações para cada um dos parâmetros separadamente. Por exemplo, se o teste de API depender de dois parâmetros: FileName e FileExtension, você poderá pensar nas possíveis variações a serem passadas para FileName e para FileExtensions separadamente da seguinte maneira:

  • FileName: a, z12390, Realllyreallyreallylonglonglonglonglonglonglonglonglong, normallength
  • FileExtension: txt, png, bat, doc, exe, bmp, wav

Agora, você pode ver que uma expansão combinatorial de força bruta do acima (4 X 7 = 28) poderia facilmente sair dos limites conforme você pensa em mais variações para adicionar à lista. Nesses cenários de caso de teste, PICT poderia adicionar muito valor gerando um conjunto compacto de resultados de parâmetros para obter cobertura combinatorial abrangente sobre os parâmetros de entrada.

Suporte a PICT no TAEF

O TAEF oferece suporte interno para testes baseados em PICT.

Para aproveitar isso, escreva o arquivo de modelo de entrada para pict.exe da mesma forma que você normalmente faria. Consulte os arquivos *.txt na pasta de exemplos mencionada acima. Pode ser útil verificar se o PICT executa como esperado no seu arquivo de modelo, testando-o primeiro no prompt de comando.

pict.exe <model file> [/e:<seed file>]

Pict.exe está disponível com o restante dos binários no compartilhamento de versão mais recente do TAEF.

Depois de terminar de criar seu arquivo de modelo (e arquivo de semente) para PICT e tê-lo verificado contra pict.exe no prompt de comando, você pode agora anotar seus testes para informar ao TAEF que eles são testes acionados por PICT. Se você estiver familiarizado com testes baseados em dados baseados em tabelas disponíveis no TAEF, você achará isso muito semelhante.

Código nativo:

1     class PictExample
2     {
3         TEST_CLASS(PictExample)
4
5         BEGIN_TEST_METHOD(SimpleTest)
6             TEST_METHOD_PROPERTY(L"DataSource", L"pict:PictExample.txt")
7         END_TEST_METHOD()
8
9         BEGIN_TEST_METHOD(TestWithSeed)
10            TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithSeed.txt")
11            TEST_METHOD_PROPERTY(L"Pict:SeedingFile", L"TestWithSeed.sed")
12            TEST_METHOD_PROPERTY(L"Pict:Timeout", L"00:01:30")
13        END_TEST_METHOD()
14
15        BEGIN_TEST_METHOD(TestWithFunction)
16            TEST_METHOD_PROPERTY(L"DataSource", L"pict:TestWithFunction.txt")
17        END_TEST_METHOD()
18    };

Código gerenciado:

1     [TestClass]
2     public class CSharpPictExample
3     {
4         [TestMethod]
5         [DataSource("pict:ConstraintsTest.txt")]
6         [TestProperty("Pict:SeedingFile", "ConstraintsTest.seed")]
7         public void ConstraintsTest()
8         {
9             ...
10        }
11
12        [TestMethod]
13        [DataSource("pict:SumofSquareRoots.txt")]
14        public void SumOfSquareRoots()
15        {
16            ...
17        }
18
19        public TestContext TestContext
20        {
21            get { return m_testContext; }
22            set { m_testContext = value; }
23        }
24
25        private TestContext m_testContext;
26    }

Conforme mostrado nos exemplos acima, você precisa especificar o nome do arquivo de modelo como DataSource. Você deve prefixar o nome do arquivo de modelo com "pict:" e fornecê-lo como o DataSource para o método de teste. No caso do teste gerenciado, assim como em qualquer outro teste controlado por dados com TAEF, você deve fornecer métodos de obtenção e definição da propriedade TestContext e ter uma instância privada igual em sua classe.

Se você quiser passar opções de comando para PICT, poderá usar metadados para essa finalidade. Use a tabela a seguir para mapear as opções de comando de Pict.exe para metadados TAEF.

sintaxe de comando pict.exe Sintaxe de metadados TAEF nativa Sintaxe de metadados TAEF gerenciada
/o:3 TEST_METHOD_PROPERTY(L"Pict:Order", L"3") [TestProperty("Pict:Order", "3")]
/d:, TEST_METHOD_PROPERTY(L"Pict:ValueSeparator", L",") [TestProperty("Pict:ValueSeparator", ",")]
/a: TEST_METHOD_PROPERTY(L"Pict:AliasSeparator", L"
/n:~ TEST_METHOD_PROPERTY(L"Pict:NegativeValuePrefix", L"~") [TestProperty("Pict:NegativeValuePrefix", "~")]
/e:test.seed TEST_METHOD_PROPERTY(L"Pict:SeedingFile", L"test.seed") [TestProperty("Pict:SeedingFile", "test.seed")]
/r TEST_METHOD_PROPERTY(L"Pict:Random", L"true") [TestProperty("Pict:Random", "true")]
/r:33 TEST_METHOD_PROPERTY(L"Pict:RandomSeed", L"33") [TestProperty("Pict:RandomSeed", "33")]
/c TEST_METHOD_PROPERTY(L"Pict:CaseSensitive", L"true") [TestProperty("Pict:CaseSensitive", "true")]

Qualquer um dos metadados acima pode ser definido no prompt de comando, na propriedade DataSource ou como metadados de nível de teste, classe ou módulo, com precedência nessa ordem. Para defini-lo no prompt de comando, use a sintaxe:

te.exe <test dll> /Pict:Order=3 /Pict:SeedingFile=test.seed

Para definir metadados na propriedade DataSource, acrescente ao nome do arquivo de modelo um caractere de ponto de interrogação (?) e, em seguida, um conjunto de pares nome = valor de metadados separados por ampersands (&). Ao usar esse método, o prefixo "Pict:" para nomes de metadados é opcional. Este é um exemplo:

TEST_METHOD_PROPERTY(L"DataSource", L"Pict:model.txt?Order=3&CaseSensitive=true&Random=true")

Nos bastidores, o TAEF fornecerá o arquivo de modelo de entrada e as opções de comando para PICT e obterá os resultados. Se PICT produzir erros ou avisos, você os verá registrados como avisos pelo TAEF. Para cada linha de saída resultante que o PICT produz, o TAEF invocará novamente o teste em questão.

Definir o valor "Pict:RandomSeed" alterará o padrão para "Pict:Random" de false para true. Dessa forma, você pode definir explicitamente "Pict:Random" como false para que o TAEF ignore "Pict:RandomSeed".

O tempo limite padrão permitido para a execução de PICT.exe nos arquivos de modelo e de entrada de semente especificados é de 5 minutos. Se o arquivo de modelo estiver mais envolvido e precisar de mais tempo do que 5 minutos para que PICT.exe retorne resultados, você pode substituir esse tempo limite especificando os metadados "Pict:Timeout", conforme mostrado no exemplo do CPP acima. No exemplo, um tempo limite de 1,5 minuto é especificado por meio do formato de tempo limite taef padrão. Assim como os outros metadados PICT, os metadados "Pict:Timeout" são herdados e, portanto, podem ser especificados para toda a classe ou módulo.

Você pode acessar os valores de dados durante uma determinada invocação de seu método de teste e seus métodos de instalação e limpeza associados da mesma maneira que você fez para testes baseados em dados baseados em tabela com TAEF - usando a classe TestData para código nativo e usando o TestContext para código gerenciado assim:

Código nativo:

1     void PictExample::SimpleTest()
2     {
3         String valueA;
4         if (SUCCEEDED(TestData::TryGetValue(L"A", valueA)))
5         {
6           Log::Comment(L"A retrieved was " + valueA);
7         }
8
9         String valueB;
10        if (SUCCEEDED(TestData::TryGetValue(L"B", valueB)))
11        {
12            Log::Comment(L"B retrieved was " + valueB);
13        }
14
15        String valueC;
16        if (SUCCEEDED(TestData::TryGetValue(L"C", valueC)))
17        {
18            Log::Comment(L"C retrieved was " + valueC);
19        }
20
21        unsigned int index;
22        if (SUCCEEDED(TestData::TryGetValue(L"index", index)))
23        {
24            Log::Comment(String().Format(L"At index %d", index));
25        }
26    }

Código gerenciado:

1      [TestClass]
2      public class CSharpPictExample
3      {
4          [TestMethod]
5          [DataSource("pict:ConstraintsTest.txt")]
6          public void ConstraintsTest()
7          {
8              Log.Comment("A is " + m_testContext.DataRow["A"]);
9              Log.Comment("B is " + m_testContext.DataRow["B"]);
10             Log.Comment("C is " + m_testContext.DataRow["C"]);
11             Log.Comment("D is " + m_testContext.DataRow["D"]);
12
13             UInt32 index = (UInt32)m_testContext.DataRow["Index"];
14             Log.Comment("At index " + index.ToString());
15        }
16
17        [TestMethod]
18        [DataSource("pict:SumofSquareRoots.txt")]
19        public void SumOfSquareRoots()
20        {
21             Log.Comment("A is " + m_testContext.DataRow["A"]);
22             Log.Comment("B is " + m_testContext.DataRow["B"]);
23
24             UInt32 index = (UInt32)m_testContext.DataRow["Index"];
25             Log.Comment("At index " + index.ToString());
26        }
27
28        public TestContext TestContext
29        {
30             get { return m_testContext; }
31             set { m_testContext = value; }
32        }
33
34        private TestContext m_testContext;
35    }

Assim como acontece com todos os testes controlados por dados no TAEF, "Index" é reservado e não deve ser usado como nome do parâmetro. O índice refere-se implicitamente ao índice da invocação do método de teste e é acessível a partir do método de teste se o teste precisar dele.

Também é importante observar que, no caso de testes baseados em PICT, o tipo de dados para todos os parâmetros é considerado WEX::Common::String (nativo), String(managed) ou VT_BSTR(script). A conversão e a interpretação são deixadas para o usuário.

Agora que você terminou de criar o teste baseado em PICT usando o TAEF, você pode invocá-lo no prompt de comando e aplicar todos os recursos de comando que o TAEF oferece: como /list para obter uma lista de todos os métodos de teste que serão gerados usando a saída PICT como dados, /listproperties para obter uma lista dos nomes dos métodos de teste junto com os metadados e os valores dos dados com os quais estão associados, etc. O importante a notar antes de começar é garantir que pict.exe esteja em seu caminho.

Veja alguns exemplos:

te Examples\CPP.Pict.Example.dll /list /name:*SimpleTest*
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CPP.Pict.Example.dll
            WEX::TestExecution::Examples::PictExample
                WEX::TestExecution::Examples::PictExample::SimpleTest#0
                WEX::TestExecution::Examples::PictExample::SimpleTest#1
                WEX::TestExecution::Examples::PictExample::SimpleTest#2
                WEX::TestExecution::Examples::PictExample::SimpleTest#3
                WEX::TestExecution::Examples::PictExample::SimpleTest#4
                WEX::TestExecution::Examples::PictExample::SimpleTest#5
                WEX::TestExecution::Examples::PictExample::SimpleTest#6
                WEX::TestExecution::Examples::PictExample::SimpleTest#7
                WEX::TestExecution::Examples::PictExample::SimpleTest#8
                WEX::TestExecution::Examples::PictExample::SimpleTest#9
                WEX::TestExecution::Examples::PictExample::SimpleTest#10
                WEX::TestExecution::Examples::PictExample::SimpleTest#11
                WEX::TestExecution::Examples::PictExample::SimpleTest#12
                WEX::TestExecution::Examples::PictExample::SimpleTest#13
                WEX::TestExecution::Examples::PictExample::SimpleTest#14
                WEX::TestExecution::Examples::PictExample::SimpleTest#15
                WEX::TestExecution::Examples::PictExample::SimpleTest#16
                WEX::TestExecution::Examples::PictExample::SimpleTest#17
                WEX::TestExecution::Examples::PictExample::SimpleTest#18
                WEX::TestExecution::Examples::PictExample::SimpleTest#19
                WEX::TestExecution::Examples::PictExample::SimpleTest#20
                WEX::TestExecution::Examples::PictExample::SimpleTest#21
                WEX::TestExecution::Examples::PictExample::SimpleTest#22
                WEX::TestExecution::Examples::PictExample::SimpleTest#23

Para ler mais sobre critérios de seleção (/select e /name), consulte a página wiki Seleção.

te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
                    and @Data:index>10
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CSharp.Pict.Example.dll
            WEX.Examples.CSharpPictExample
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#11
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 1
                        Data[b] = ~-1
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#12
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 2
                        Data[b] = ~-1

O exemplo acima mostra como você pode selecionar usando o índice. Você também pode optar por selecionar com base no valor de dados.

te Examples\Csharp.Pict.Example.dll /listproperties /select:"@Name='*SumofSquare*'
                    and (@Data:A='1' and @Data:B='1')"
Test Authoring and Execution Framework v2.9.3k for x86
        f:\ Examples\CSharp.Pict.Example.dll
            WEX.Examples.CSharpPictExample
                WEX.Examples.CSharpPictExample.SumOfSquareRoots#8
                        Property[DataSource] = pict:SumofSquareRoots.txt
                        Data[a] = 1
                        Data[b] = 1

Cache de resultados PICT

Algum arquivo de modelo pode ficar muito complexo e pode exigir mais tempo para ser processado por Pict.exe. O TAEF tenta reduzir o tempo de processamento dos resultados armazenando em cache os resultados durante uma determinada execução de Te.exe. Se um teste subsequente na mesma execução se referir à mesma combinação de modelo e arquivo de semente, o TAEF usará os resultados em cache. Por padrão, no final de cada execução, os resultados armazenados em cache são excluídos.

Se você quiser continuar a aproveitar os resultados armazenados em cache em execuções subsequentes, poderá especificar a opção "/persistPictResults" no prompt de comando durante a execução. Sempre que você especificar "/persistPictResults" para seu comando, a primeira execução realmente executará pict.exe e pode levar muito tempo, mas todas as execuções subsequentes usarão os resultados armazenados em cache nos casos em que o modelo e o arquivo de semente não tiverem sido modificados. Observação: você precisará continuar especificando "/persistPictResults" para execuções subsequentes. Qualquer execução subsequente em que você não especificá-la excluirá os resultados armazenados em cache no final dessa execução.

Se persistir os resultados do PICT e usar dados armazenados em cache for algo que você deseja fazer por padrão, você poderá defini-lo como parte de sua variável de ambiente te_cmd conforme mostrado abaixo e eliminar a necessidade de especificá-los em cada execução. Consulte a execução de testes para obter mais detalhes sobre te_cmd.

set te_cmd = /persistPictResults

Os arquivos de resultado armazenados em cache são armazenados em uma pasta chamada "TAEF-PICT" no diretório %temp%, se Te.exe tiver acesso a ele ou no diretório de execução atual de onde Te.exe foi iniciado. A única vez que você pode ter os resultados em um estado inconsistente é se você atingir Ctrl + C durante a execução. Nesse caso, o TAEF tentará excluir os resultados armazenados em cache, mas, se não for possível, você verá uma mensagem de erro a respeito. O erro solicitará que você exclua o local de resultados armazenados em cache. Não fazer isso pode resultar em um comportamento indefinido ou incorreto em testes subsequentes.

Com o suporte interno do PICT no TAEF, agora você pode aproveitar ao máximo os recursos no PICT, bem como os recursos no TAEF na automação de teste.

DataSource como um recurso

Você pode adicionar modelos PICT e arquivos de propagação como recursos em seu módulo de teste.

No código nativo, isso é feito especificando o nome do recurso em vez do nome do arquivo nos metadados do DataSource. Este é um exemplo:

BEGIN_TEST_METHOD(ResourceNameDataSource)
    TEST_METHOD_PROPERTY(L"DataSource", L"Pict:MyModelResourceName?SeedingFile=MySeedingResourceName")
END_TEST_METHOD()

"MyModelResourceName" e "MySeedingResourceName" são os nomes de recursos definidos em um arquivo .rc. O tipo de recurso precisa ser DATAFILE, ao contrário das fontes de dados de tabela em que o tipo de recurso precisa ser DATASOURCE_XML.

MyModelResourceName DATAFILE "model.txt"
MySeedingResourceName DATAFILE "seed.txt"

O valor dos metadados do DataSource permanecerá o mesmo de quando o modelo era um arquivo. Da mesma forma no código nativo, você pode fazer com que o nome do recurso seja o mesmo que o nome do arquivo. O TAEF primeiro procurará a presença do arquivo real com o nome DataSource. Se o arquivo não for encontrado, ele continuará examinando os recursos do módulo de teste. Como alterar o DataSource armazenado no recurso requer recompilação, você pode aproveitar esse design copiando o arquivo DataSource para o mesmo local que a dll de teste durante o desenvolvimento (e nomeando o nome do recurso como o mesmo que o nome do arquivo). Depois de concluir o teste, mova (não copie) o arquivo de volta para o diretório de código e recompile para inserir o recurso.