Рубрики
Uncategorized

Teste de Integração com sqlserver e Azure Devops

Há poucos dias atrás fiz uma extrementação Para Integradar Meus Testes COM O SQL Server. Mot … Помечено тестированием, дежоптом, Azure, Dotnet.

Há poucos dias atrás fiz uma extrementação Para Integradar Meus Testes COM O SQL Server.

Мотиваção.

O que me levou escrever Esse Tipo de Teste Foi:

  • Quero Escrever UM Testes Que Seja O Mais Aderente Ao Ambiente de Produção — Ou Seja, SE VAI RODAR EM SQL Server — Tenho Que Escrever UM Testes Que Rode EM SQL Server.
  • Quero Testar Communitas Mais Complys;
  • Quero Testar Cada Método Da Minha Classe de Repositório, COM Cenário Próprio, SEM Precisar Rodar o Sistema Inteiro Para Fazer Realizar Este Teste;
  • Возможность Testes Transacionais

Para Radar OS Testes Segui OS Seguintes Passos:

  • Montei UM SQL Server Em UM-контейнер;
  • ESCREVI UM Código Para Criação da Estrutura de Banco, Cenário E Execução Dos Teste de Repositórios;
  • Escrevi OS Testes Propramente Ditos;
  • Configurei o Pobile DO DO AZURE PARA SUBIR UMA Instância DO SQL Server EM Tempo de Build Antes de Rodar OS Testes Integrados Com Repositórios.

Exemplo Do Método de Repositório Que Quero Testar

public async Task> GetByEmailAsync(string email) 
{ 
     var query = @" 
SELECT  
      u.Id, u.FirstName, u.LastName, u.PersonalIdentificationNumber, 
      u.Email, u.ProfileCode, u.DateCreated 
FROM  
          [dbo].[User] u                 
WHERE  
    u.Email = @Email 
    AND u.TenantId = @TenantId"; 

    return await _dapperContext.DapperConnection 
                   .QueryAsync( 
                        query, new { Email = email, TenantId = this.TenantId() }); 
} 

Sqlserver no meu ambiente de desenvolvimento

CRIEI UM-контейнер (Docker) Para Instância DO SQL Server. Para Subir O. SQL Server Disponibilizo Meu Docker-Compose que Utilizei Para Inciblização do контейнер;

Meu Sistema Operational Eo Windows Então, Utilizei o Докер Для Windows Disponível Aqui.

Salve Ur Arquivo EM Alguma Pasta No Seu Commentador Com Esse Conteúdo. Нет Meu Ambiente, Salvei Aqui [ C: _devz \ dockers \ sqlserver]

Docker-Compose.yml.yml.yml

version: '3' 

services: 
    db: 
        image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu 
        environment: 
            SA_PASSWORD: "Q1w2e3r4!" 
            ACCEPT_EULA: Y 
            MSSQL_PID: Express 
        ports: 
            - "1433:1433" 
        volumes: 
            - mssql-volume:/var/lib/mssql 
        networks: 
            - mssql_docknet            
networks: 
    mssql_docknet: 
        driver: bridge                
volumes: 
    mssql-volume:    

Контейнер Para Executar O, выполните не подсказку COMO ABAIXO:

> cd C:\_devz\Dockers\sqlserver [Esse é o local onde está o docker-compose.yml] 

> docker-compose up –d 

Código Para Estrutura E Conexão Com Banco de Dados

Para Que Meu Teste Funcionasse Precisei de UMA Instância DO SQL Server Funcionando — Instância Que Configurei Acima;

Para Ter Cenários e Testes Независимые, АНТЕС Que OS Testes Fossem Executados:

  • Criei UMA Classe de Contexto Compartilhado Que o Xunit Disponibiliza;
  • Эссе контекторская кримия О Банко де Дадо;
  • Esse Contexto Cria как Tabelas Configuradas не существует;
[CollectionDefinition("DatabaseTestCollection")] 
public class DatabaseCollection : ICollectionFixture 
{ 
} 

COM ESSA CLASSE EU DEASTI UM CONTEXTO GLOBAL PARA TODOS OS MEUS TESTES. Essa Classe é Assim Mesmo — NãO TEM Código Nenhum Em Seu Corpo.

NA CLASSE База данныхFixture Tenho As Informações do Banco de Dados E A A Enactização do Banco;

Nesta Classe Configurei As Informações делает сущность E делает DAPPER; COM ESSAS Informações, Meu Banco de Dados de Teste É CriaDo;

public DapperContext _dapper; 
public IConfiguration _configuration; 

public DatabaseFixture() 
{ 
////minha string de conexão que se conecta com o container montado
    var connectionString = $"Server=localhost;Database=gamificacao_test;User ID=sa;Password=Q1w2e3r4!;Trusted_Connection=False;"; 

////Adicionei algumas configurações para rastrear problemas de banco ao rodar meus testes
    ContextOptions = new DbContextOptionsBuilder() 
                        .UseSqlServer(connectionString) 
                        .EnableSensitiveDataLogging() 
          .UseLoggerFactory(LoggerFactory.Create(builder => { builder.AddDebug(); })) 
                        .Options; 

////Como se trata de um cenário de testes algumas coisas coloquei em memória por não ser relevante para o testes
    var myConfiguration = new Dictionary 
    { 
        { "ConnectionStrings:GamificacaoDB", connectionString } 
    }; 

    _configuration = new ConfigurationBuilder() 
        .AddInMemoryCollection(myConfiguration) 
        .Build(); 

    IdentityServiceMock = new Mock(); 
    IdentityServiceMock.Setup(x => x.GetTenantId()) 
        .Returns("Wx1"); 

    Context = new EntityContext(ContextOptions, IdentityServiceMock.Object); 

    _dapper = new DapperContext(_configuration); 

    //// Cria o meu banco de testes
    InitializeDatabase();
} 

////Repositorios da minha API que pretendo testar
public ActionRepository ActionRepository {  

    get { return new ActionRepository(Context, _dapper, IdentityServiceMock.Object); } } 

public UserRepository UserRepository {  

    get { return new UserRepository(Context, _dapper, IdentityServiceMock.Object); } } 

protected virtual void InitializeDatabase() 
        { 
            using (var context = new EntityContext(ContextOptions, IdentityServiceMock.Object)) 
            { 
                context.Database.EnsureDeleted(); 
                context.Database.EnsureCreated(); 
            } 
        } 

O repositório que retendo testar

ESTOU TESTANDO O REPOSITORIOO de Usuários ( UseRepository ). O Método Em Questão Está Utilizando Dapper E Minha Consulta é Muito Smops.

public async Task> GetByEmailAsync(string email) 
{ 
     var query = @" 
SELECT  
      u.Id, u.FirstName, u.LastName, u.PersonalIdentificationNumber, 
      u.Email, u.ProfileCode, u.DateCreated 
FROM  
          [dbo].[User] u                 
WHERE  
    u.Email = @Email 
    AND u.TenantId = @TenantId"; 

    return await _dapperContext.DapperConnection 
                   .QueryAsync( 
                        query, new { Email = email, TenantId = this.TenantId() }); 
} 

O Темит

Quando instância do sqlserver iniciou nan thenho nenhuma informação nas tabelas para executar os testes. Então, Preciso КРИРСК ЭСКАЗЫ ДАДОС. Para Isso, Utilizei As Mesmas Classes de Criação de objetos que já temos em nossa estrutura. Veja No Teste Abaixo: Criei 1 Usuário.

Para o Contexto DOS Testes Criei Um Método Estendido Para как Estidades. Nesse Método Consigo Inserir No Banco de Dados o que stesta u Estida. ISSO FACILITA OLLUSãO DE DADOS NAS TABELAS SEM Обучение NAS CAMAR O Repositório Para Inserir.

public static class EntityExtensions 
{ 
    public static T Persist( 
           this T entity,  
           EntityContext context) where T : class 
    { 
        context.Add(entity); 
        context.SaveChanges(); 

        return entity; 
    } 
} 

Então, Na linha onde temos Пользователь. Сохраняться (_databasefixture. Контекст) Табела Пользователь Será Persistida.

O mesmo aconteceria com routoS objetos onde chamando o .persist ().

[Fact] 
public async Task GetByMail_TestAsync() 
{ 
    //Cenario 
    var tiago = new Domain.Models.User 
    { 
        Email = "tiagobrito@wizsolucoes.com.br", 
        FirstName = "Tiago", 
        LastName = "Brito", 
        ProfileCode = "A", 
        PersonalIdentificationNumber = "15476338731" 
    }; 

    tiago.Persist(_databaseFixture.Context); 

    //Execução 
    var userToCompare = await _databaseFixture.UserRepository                                 .GetByEmailAsync("tiagobrito@wizsolucoes.com.br"); 

     ///Validação 
    userToCompare.ElementAt(0).FirstName.Should().Be("Tiago"); 
    userToCompare.ElementAt(0).LastName.Should().Be("Brito"); 
} 
 var userToCompare = await _databaseFixture.UserRepository                           .GetByEmailAsync("tiagobrito@wizsolucoes.com.br"); 

Na linha acima temos execução do Repositório. Nesta retapa, Тодос О.С. Меюс Дадос Я Эстао Персистидос E, SE ALIMESEI AS TABELA Corretamente E Minha Classe de Repositório Ediver Com A Consuma Correta, ОС Dados Virão. Estamos Testando Apenas Essa Unidade. FICA BEM STRPERS E NãO Preciso Rodar o Sistema Inteiro.

PARA валидар ОС Retornos Utilizamos o que já conheecemos

ЕС Utilizo UMA Biblioteca Para Утверждать Fluente — Тео-нибудь Лейтуру Do Teste Fica Bem Legal. Поде Ser Encontrada Aqui.

userToCompare.ElementAt(0).FirstName.Should().Be("Tiago"); 
userToCompare.ElementAt(0).LastName.Should().Be("Brito"); 

Configuração Do Parian Para Testes de Integração COM SQL Server нет лазу

COMO Mencionado No Lameiro Tópico, Utilizo UM Контейнер Para Subir UMA Instancia DO SQL Server Express E Realizar OS Testes. Нет Azure DevOps Fiz o Mesmo: нет Arquivo Azure-Pipelines.yml DO PROJETO DESTEVI O Recurso que Precisava NAS Extensões, Segundo O Novo Modelo de Pipeliel, icitifiquei o serviço que utilizar. Нет Caso, O SQL Server.

# ASP.NET Core
# Build a Web project that uses ASP.NET Core.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core
# YAML reference:
# https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema

variables: 
    azResourceName: 'meu-projeto'

resources:
  repositories:
    - repository: dotnettemplate
      type: git  
      name: meurepositorio/modelos
      ref: refs/tags/v1.1
  containers:
  - container: mssql
    image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
    ports: 
      - 1433:1433
    options: -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Q1w2e3r4!' -e 'MSSQL_PID=Express'

pool:
  vmImage: 'ubuntu-latest'

schedules:
  - cron: "0 0 * * *"
    displayName: Build Noturno
    always: true
    branches:
      include:
        - master

trigger:
  batch: true
  paths:
    exclude:
    - README.md

stages:
- stage: Build
  pool: Wiz Hosted Ubuntu 1604
  jobs:
    - job:
      continueOnError: true
      services:
        localhostsqlserver: mssql
      steps:
          #Essas linhas com powershell são apenas para testes. podem ser removidas
        - task: PowerShell@2
          displayName: 'delay 10'
          inputs:
            targetType: 'inline'
            script: |
              # Write your PowerShell commands here.
              start-sleep -s 10
        - task: CmdLine@2
          inputs:
            script: 'sqlcmd -S localhost -d master -U sa -P Q1w2e3r4! -Q "SELECT @@version;"'
         #Esse template compila aplicações .net
        - template: dotnetcore.yml@dotnettemplate
- stage: Uat
  condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'master'), contains(variables['Build.SourceBranch'], 'releases')))
  dependsOn: [Build]
  jobs:
    - deployment: 
      environment: staging
      strategy:
        runOnce:
          deploy:                              
            steps:
            - task: AzureRmWebAppDeployment@4
              displayName: Publish 
              inputs:
                ConnectionType: 'AzureRM'
                azureSubscription: 'xxx'
                appType: 'webApp'
                WebAppName: '$(azResourceName)-hml-api'
                packageForLinux: '$(Pipeline.Workspace)/drop/**/*.zip'

O YML Abaixo é Bem Simplififificado E É O Que Utilizamos Na Wiz. Isso Porque Nossa Equipe de Guantanança Trabalhou Algum Tempo Para Torná-Lo Smarts Assim.

resources: 
  repositories: 
  - repository: coretemplate 
    type: git 
    name: meu/repositorio 

  containers: 
  - container: mssql 
    image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu 
    env: 
      ACCEPT_EULA: Y 
      SA_PASSWORD: Q1w2e3r4! 
      MSSQL_PID: Express 
    ports:  
      - 1433:1433 
    options: --name mssql 

pool: 
  vmImage: 'ubuntu-latest' 

schedules: 
  - cron: "0 0 * * *" 
    displayName: Build Noturno 
    always: true 
    branches: 
      include: 
        - master 
trigger: 
  batch: true 
  paths: 
    exclude: 
    - README.md 

extends: 
  template: main.yml@coretemplate 
  parameters: 
    technology: 'dotnetcore' 
    dotnetcoreAppType: 'apiApp' 
    azResourceName: 'gamificacao' 
    azSubscriptionUAT: 'xxx' 
    azSubscriptionPRD: 'xxx' 
    dotnetcoreDotNetVersion: '3.x' 
    dotnetcoreBuildProject: '**/*[API].csproj' 
    dotnetcoreBuildConfiguration: Release 
    dotnetcoreTestProject: '**/*[Tt]ests/*.csproj' 
    dotnetcoreNugetFeed: 09b2821a-2950-4eff-a722-dbc8adf4da55 
    buildServices: 
      mssql: mssql 
    releaseServices: 
      mssql: mssql 

Нет Azure PodeMos Visualizar OS Resultaldos

Оригинал: «https://dev.to/devzwiz/teste-de-integracao-com-sqlserver-e-azure-devops-2cl»