Olá a todos. Hoje compartilhamos com vocês a parte final do artigo , cuja tradução foi preparada especialmente para os alunos do curso .

Teste de Implantação
O estilo de teste abordado é uma abordagem poderosa, que nos permite realizar testes de caixa branca para verificar a estrutura interna do nosso código de infraestrutura. No entanto, ele limita um pouco o que podemos testar. Os testes são realizados com base em um plano de implantação em memória, criado pelo Pulumi antes da implantação real, e portanto a própria implantação não pode ser testada. Para esses casos, o Pulumi possui um framework de testes de integração. E essas duas abordagens funcionam muito bem juntas!
O framework de teste de integração do Pulumi é escrito em Go, e é com ele que testamos a maior parte do nosso código interno. Se a abordagem de teste de unidade discutida anteriormente parecia mais um teste de caixa branca, o teste de integração é mais como um teste de caixa preta. (Existem também opções de teste interno rigoroso.) Este framework foi criado para assumir um programa Pulumi completo e executar várias operações de ciclo de vida, como implantar um novo stack do zero, atualizá-lo com variações e removê-lo, possivelmente várias vezes. Nós os executamos regularmente (por exemplo, à noite) e como testes de estresse.
(Nós , capacidades semelhantes de teste de integração estejam disponíveis no SDK nativo dos idiomas. Você pode usar o framework de teste de integração Go independentemente do idioma em que seu programa Pulumi foi escrito).
Ao executar um programa usando este framework, você pode verificar o seguinte:
- O código do seu projeto é sintaticamente correto e funciona sem erros.
- As configurações de configuração do stack e segredos funcionam e são interpretadas corretamente.
- Seu projeto pode ser implantado com sucesso no provedor de nuvem que você escolheu.
- Seu projeto pode ser atualizado com sucesso de um estado inicial para N outros estados.
- Seu projeto pode ser destruído e removido com sucesso do seu provedor de nuvem.
Como veremos em breve, esse framework também pode ser usado para realizar validação em tempo de execução.
Teste de integração simples
Para ver isso em ação, vamos olhar o repositório pulumi/exemplos, pois nossa equipe e a comunidade Pulumi o utilizam para testar suas próprias pull requests, commits e builds noturnas.
Abaixo está um teste simplificado do nosso :
example_test.go:
package test
import (
"os"
"path"
"testing"
"github.com/pulumi/pulumi/pkg/testing/integration"
)
func TestExamples(t *testing.T) {
awsRegion := os.Getenv("AWS_REGION")
if awsRegion == "" {
awsRegion = "us-west-1"
}
cwd, _ := os.Getwd()
integration.ProgramTest(t, &integration.ProgramTestOptions{
Quick: true,
SkipRefresh: true,
Dir: path.Join(cwd, "..", "..", "aws-js-s3-folder"),
Config: map[string]string{
"aws:region": awsRegion,
},
})
} Este teste passa pelo ciclo de vida básico de criação, modificação e destruição de uma pilha para a pasta aws-js-s3-folder. Vai levar cerca de um minuto para relatar o teste passado:
$ go test .
PASS
ok ... 43.993s Existem muitos parâmetros para configurar o comportamento desses testes. A lista completa de opções pode ser vista ProgramTestOptions. Por exemplo, você pode configurar o endpoint do Jaeger para rastreamento (Rastreamento), indicar que você espera a falha do teste ao realizar testes negativos (ExpectFailure), aplicar uma série de “edições” ao programa para transições de estado sequenciais (EditDirs) e muito mais. Vamos ver como usá-los para verificar a implantação do aplicativo.
Verificando as propriedades dos recursos
A integração mencionada acima garante que nosso programa "funciona" — ele não falha. Mas e se quisermos verificar as propriedades da pilha resultante? Por exemplo, se certos tipos de recursos foram (ou não) provisionados e se eles têm atributos específicos.
Parâmetro ExtraRuntimeValidation para ProgramTestOptions nos permite olhar para o estado que o Pulumi captura após a implantação (estado pós-implantação), para que possamos fazer verificações adicionais. Isso inclui um snapshot completo do estado da pilha resultante, incluindo configuração, valores de saída exportados, todos os recursos e os valores de suas propriedades, bem como todas as dependências entre os recursos.
Para ver um exemplo básico disso, vamos verificar se nosso programa cria um Bucket S3:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// como antes...
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
var foundBuckets int
for _, res := range stack.Deployment.Resources {
if res.Type == "aws:s3/bucket:Bucket" {
foundBuckets++
}
}
assert.Equal(t, 1, foundBuckets, "Esperado encontrar um único AWS S3 Bucket")
},
})Agora, quando executarmos o go test, ele não apenas passará por uma bateria de testes do ciclo de vida, mas também, após o sucesso no deployment da pilha, realizará uma verificação adicional do estado resultante.
Testes de Runtime
Até agora, todos os testes foram exclusivamente sobre o comportamento na implementação e sobre o modelo de recursos do Pulumi. O que fazer se você quiser verificar se a infraestrutura que preparou realmente funciona? Por exemplo, se a máquina virtual está operando, se o bucket S3 contém o que esperamos, e assim por diante.
Você pode já ter adivinhado como fazer isso: a opção ExtraRuntimeValidation para ProgramTestOptions — é uma ótima oportunidade para isso. Neste estágio, você executa um teste Go arbitrário com acesso ao estado completo dos recursos do seu programa. Esse estado inclui informações como endereços IP das máquinas virtuais, URLs e tudo o que é necessário para a interação real com os aplicativos e a infraestrutura de nuvem obtidos.
Por exemplo, nosso programa de teste exporta a propriedade webEndpoint do bucket chamado websiteUrl, que representa a URL completa pela qual podemos acessar o index document. Embora pudéssemos vasculhar o arquivo de estado para encontrar bucket e ler essa propriedade diretamente, em muitos casos nossas pilhas exportam propriedades úteis, como essa, que são convenientes para usarmos na verificação:
integration.ProgramTest(t, &integration.ProgramTestOptions{
// como antes ...
ExtraRuntimeValidation: func(t *testing.T, stack integration.RuntimeValidationStackInfo) {
url := "http://" + stack.Outputs["websiteUrl"].(string)
resp, err := http.Get(url)
if !assert.NoError(t, err) {
return
}
if !assert.Equal(t, 200, resp.StatusCode) {
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if !assert.NoError(t, err) {
return
}
assert.Contains(t, string(body), "Olá, Pulumi!")
},
}) Como nossos testes de runtime anteriores, esta verificação será executada imediatamente após a criação da pilha, e tudo isso em resposta a uma simples chamada go test. E isso é apenas a ponta do iceberg — todas as funcionalidades de teste do Go estão disponíveis para você escrever no código.
Integração contínua da infraestrutura
É bom ter a capacidade de executar testes em um notebook quando são feitas muitas alterações na infraestrutura, para verificar antes de enviar para revisão de código. Mas nós e muitos de nossos clientes testamos a infraestrutura em várias etapas do ciclo de desenvolvimento:
- Em cada pull request aberto para teste antes da fusão.
- Em resposta a cada commit, para verificar novamente se a fusão foi feita corretamente.
- Periodicamente, como por exemplo, à noite ou semanalmente para testes adicionais.
- No âmbito de testes de desempenho ou testes de estresse, que geralmente são realizados ao longo de um longo período e executam testes em paralelo e/ou implementam o mesmo programa várias vezes.
Para cada um deles, o Pulumi oferece integração com seu sistema de integração contínua favorito. Com a integração contínua, isso lhe dá a mesma cobertura de testes para sua infraestrutura como para o software de aplicação.
O Pulumi tem suporte para sistemas CI populares. Aqui estão alguns deles:
Para mais informações, consulte a documentação sobre .
Ambientes efêmeros
Uma possibilidade muito poderosa que surge é a capacidade de implantar ambientes efêmeros exclusivamente para fins de teste de aceitação. O conceito de o Pulumi foi projetado para implantar e demitir facilmente ambientes totalmente isolados e independentes, tudo com alguns comandos simples de CLI ou usando um framework de teste de integração.
Se você está usando o GitHub, o Pulumi oferece , que ajuda você a conectar testes de aceitação aos pull requests dentro do seu pipeline CI. Basta instalar o aplicativo no repositório do GitHub, e o Pulumi no seu CI para que as informações sobre a prévia da infraestrutura, atualizações e resultados dos testes sejam adicionadas aos pull requests:

Ao usar o Pulumi para seus testes de aceitação, você terá novas possibilidades de automação que melhorarão a produtividade da equipe e darão confiança na qualidade das mudanças.
Resultado
Neste artigo, vimos que, ao utilizar linguagens de programação de propósito geral, temos acesso a muitos métodos de desenvolvimento de software que foram úteis na criação de nossas aplicações. Eles incluem testes de unidade, testes de integração, bem como sua interação para realizar testes de runtime extensivos. Os testes podem ser facilmente executados sob demanda ou em seu sistema de CI.
Pulumi — um software de código aberto, é gratuito para uso e funciona com suas linguagens de programação e nuvens favoritas — !
→
Fonte: habr.com
