SlideShare une entreprise Scribd logo
Les tests
comportementaux avec
ASP.Net Core
@arnaudauroux
arnaud@auroux.me
geeklearning.io/author/Arnaud
github.com/arnaudauroux
Tests automatisés : Objectifs
• Fiabilité
• Réutilisabilité
• Détection précoce des problèmes
• Parallélisme
• Documentation
• Volume
• …
Plusieurs choix
TESTING
unit
integration
user interface
load
…
regression
functional
accessibility
smoke
keyword comportement
Plusieurs choix
TESTING
unit
integration
user interface
load
…
regression
functional
accessibility
smoke
keyword comportement
Unit testing
« Une unité représente la plus petite partie testable d’une application »
• Séparation des responsabilités
• Isolation des couches
• Approche par contrat
Mocks / Stubs / Tests unitaires = CODE =
Plusieurs choix
TESTING
unit
integration
user interface
load
…
regression
functional
accessibility
smoke
keyword comportement
Integration testing
« Valider qu’une solution et ses dépendances externes
une fois assemblées fonctionne »
• Configuration
• Environnement d’intégration
• …
=
Plusieurs choix
TESTING
unit
integration
user interface
load
…
regression
functional
accessibility
smoke
keyword comportement
Behavior testing
« Valider un scénario fonctionnel sans dépendance aux détails
d’implémentation »
• Ecrire le minimum de code pour tester le maximum d’un scenario
fonctionnel
• Couvrir facilement un scénario de bout en bout
• Abstraction des dépendances externes
ASP.NET Core et Behavior testing
• WebHostBuilder
• Startup
 ConfigurationServices()
 Configure()
• EntityFrameworkCore
 SQLite (in-memory mode)
• TestServer
ASP.NET Core et Behavior testing
Startup
Standard Configuration Service Test Configuration Service
WebApp TestServer
WebHost
ASP.NET Core et Behavior testing
public class TestStartupConfigurationService : IStartupConfigurationService
{
public virtual void ConfigureEnvironment(IHostingEnvironment env)
{
env.EnvironmentName = "Test"
}
public virtual void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration)
{
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" };
var connectionString = connectionStringBuilder.ToString();
var connection = new SqliteConnection(connectionString);
services.AddDbContext<DbContext>(options => options.UseSqlite(connection));
}
public virtual void Configure(IApplicationBuilder app, IHostingEnvironment env, …)
{
…
dbContext.Database.EnsureCreated();
…
}
}
Exemple - TestStartupConfigurationService :
ASP.NET Core et Behavior testing
Exemple - StandardStartupConfigurationService :
public class StartupConfigurationService : IStartupConfigurationService
{
public virtual void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{ }
public virtual void ConfigureEnvironment(IHostingEnvironment env)
{ }
public virtual void ConfigureService(IServiceCollection services, IConfigurationRoot configuration)
{
services.AddDbContext<DbContext>(options => options.UseSqlServer(@"[SQL_CONNECTION_STRING]"));
}
}
ASP.NET Core et Behavior testing
new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.ConfigureServices(s => s.AddSingleton<IStartupConfigurationService,
StartupConfigurationService>())
.Build()
.Run();
Exemple – Program.Main() :
ASP.NET Core et Behavior testing
public class Startup
{
private IStartupConfigurationService externalStartupConfiguration;
public Startup(IHostingEnvironment env, IStartupConfigurationService externalStartupConfiguration)
{
this.externalStartupConfiguration = externalStartupConfiguration;
this.externalStartupConfiguration.ConfigureEnvironment(env);
…
}
public void ConfigureServices(IServiceCollection services)
{
…
this.externalStartupConfiguration.ConfigureServices(services, Configuration);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
this.externalStartupConfiguration.Configure(app, env, loggerFactory, Configuration);
…
}
}
Exemple – Startup :
ASP.NET Core et Behavior testing
Exemple – TestMethod :
[TestMethod]
public void TestScenario()
{
Data[] data = CreateTestScenarioDataIntoInMemoryDb();
var webHostBuilder = new WebHostBuilder();
webHostBuilder.ConfigureServices(
s => s.AddSingleton<IStartupConfigurationService, TestStartupConfigurationService<DbContext>> ());
webHostBuilder.UseStartup<Startup>();
var testServer = new TestServer(webHostBuilder);
var response = testServer.CreateClient().GetAsync("/api/data").Result;
response.EnsureSuccessStatusCode();
var result = response.Content.ReadAsAsync<Data[]>().Result;
Assert.AreEqual(data.Length, result.Length);
for (int i = 0; i < data.Length; i++)
{
Assert.AreEqual(data[i], result[i]);
}
}
ASP.NET Core et Behavior testing
SpecFlow
• Description naturelle d’un scénario
• Abstraction du contexte technique
• Semi-intégration à NET Core 2.0
ASP.NET Core et Behavior testing
Feature: Get blogs
In order to list blogs
I want to get the list of blogs
Background:
Given A configured environment
Scenario: Get blogs should be ok
Given the following blogs
| Url |
| http://blog1.io |
| http://blog2.io |
When I get the list of blogs from Api
Then the result must be the following list
| Url |
| http://blog1.io |
| http://blog2.io |
[Binding]
public class MainSteps
{
[Given(@"A configured environment")]
public void GivenAWorkingEnvironment()
{}
[Given(@"the following blogs")]
public void GivenTheFollowingBlogs(Table table)
{}
[When(@"I get the list of blogs from Api")]
public void WhenIGetTheListOfBlogs()
{}
[Then(@"the result must be the following list")]
public void ThenTheResultMustBeTheFollowingList(Table
expectedResult)
{}
}
SpecFlow
ASP.NET Core et Behavior testing
Aller plus loin – Test de la stack MVC
• Gestion du ViewModel
• Gestion de l’Anti Forgery Token
• Gestion des dépendances Razor (.deps.json)
ASP.NET Core et Behavior testing
Aller plus loin – Gestion de l’identité
• Développement de son propre AuthenticationScheme
 AuthenticationSchemeOptions
 Définition des informations de l’identité de test
 AuthenticationHandler<SchemeOptions>
 Création de l’identité de test
 AuthenticationBuilder
 Création du schéma d’authentification à partir des options et du handler
ASP.NET Core et Behavior testing
• Série d’article sur les tests comportementaux avec ASP.NET Core
 http://geeklearning.io/a-different-approach-to-test-your-asp-net-core-
application/
• Projet GitHub
 https://github.com/geeklearningio/Testavior
• Packages nuget
 https://www.nuget.org/packages/GeekLearning.Testavior
 https://www.nuget.org/packages/GeekLearning.Testavior.Configuration

Contenu connexe

PPTX
Gatling Tool in Action at DevoxxFR 2012
PDF
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
PDF
Concevoir, développer et sécuriser des micro-services avec Spring Boot
PDF
Automatiser les tests d'acceptation : comment s'y prendre ?
PPT
Apache ANT
PDF
ParisJUG Spring Boot
PDF
DevoxxFR 2013 - Arquillian
PPTX
Retours Devoxx France 2016
Gatling Tool in Action at DevoxxFR 2012
Démo Gatling au Performance User Group de Casablanca - 25 sept 2014
Concevoir, développer et sécuriser des micro-services avec Spring Boot
Automatiser les tests d'acceptation : comment s'y prendre ?
Apache ANT
ParisJUG Spring Boot
DevoxxFR 2013 - Arquillian
Retours Devoxx France 2016

Tendances (6)

PDF
Introduction aux Web components (DNG Consulting)
PPTX
Angular + JHipster @ Paris JUG
PDF
Spring Batch
PDF
Introduction à React
PDF
Gatekeeper par Guillaume Faure
PPTX
Aspnetcore introduction
Introduction aux Web components (DNG Consulting)
Angular + JHipster @ Paris JUG
Spring Batch
Introduction à React
Gatekeeper par Guillaume Faure
Aspnetcore introduction
Publicité

Plus de Arnaud Auroux (8)

PPTX
Conférence windows phone 7
PPTX
Visual studio online
PPTX
Accéder aux données avec le windows runtime
PPTX
Développement d'un composant win rt
PPTX
Réutilisation de code entre windows 8 et windows phone 8
PPTX
Tech days 2012 mvvm de a à z
PPTX
Industrialiser le développement avec silverlight 4 et wcf ria services
PPTX
Cas Pratique Du Mode DéConnecté De Silverlight
Conférence windows phone 7
Visual studio online
Accéder aux données avec le windows runtime
Développement d'un composant win rt
Réutilisation de code entre windows 8 et windows phone 8
Tech days 2012 mvvm de a à z
Industrialiser le développement avec silverlight 4 et wcf ria services
Cas Pratique Du Mode DéConnecté De Silverlight
Publicité

Les tests comportementaux avec aspnet core

  • 1. Les tests comportementaux avec ASP.Net Core @arnaudauroux arnaud@auroux.me geeklearning.io/author/Arnaud github.com/arnaudauroux
  • 2. Tests automatisés : Objectifs • Fiabilité • Réutilisabilité • Détection précoce des problèmes • Parallélisme • Documentation • Volume • …
  • 5. Unit testing « Une unité représente la plus petite partie testable d’une application » • Séparation des responsabilités • Isolation des couches • Approche par contrat Mocks / Stubs / Tests unitaires = CODE =
  • 7. Integration testing « Valider qu’une solution et ses dépendances externes une fois assemblées fonctionne » • Configuration • Environnement d’intégration • … =
  • 9. Behavior testing « Valider un scénario fonctionnel sans dépendance aux détails d’implémentation » • Ecrire le minimum de code pour tester le maximum d’un scenario fonctionnel • Couvrir facilement un scénario de bout en bout • Abstraction des dépendances externes
  • 10. ASP.NET Core et Behavior testing • WebHostBuilder • Startup  ConfigurationServices()  Configure() • EntityFrameworkCore  SQLite (in-memory mode) • TestServer
  • 11. ASP.NET Core et Behavior testing Startup Standard Configuration Service Test Configuration Service WebApp TestServer WebHost
  • 12. ASP.NET Core et Behavior testing public class TestStartupConfigurationService : IStartupConfigurationService { public virtual void ConfigureEnvironment(IHostingEnvironment env) { env.EnvironmentName = "Test" } public virtual void ConfigureServices(IServiceCollection services, IConfigurationRoot configuration) { var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" }; var connectionString = connectionStringBuilder.ToString(); var connection = new SqliteConnection(connectionString); services.AddDbContext<DbContext>(options => options.UseSqlite(connection)); } public virtual void Configure(IApplicationBuilder app, IHostingEnvironment env, …) { … dbContext.Database.EnsureCreated(); … } } Exemple - TestStartupConfigurationService :
  • 13. ASP.NET Core et Behavior testing Exemple - StandardStartupConfigurationService : public class StartupConfigurationService : IStartupConfigurationService { public virtual void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { } public virtual void ConfigureEnvironment(IHostingEnvironment env) { } public virtual void ConfigureService(IServiceCollection services, IConfigurationRoot configuration) { services.AddDbContext<DbContext>(options => options.UseSqlServer(@"[SQL_CONNECTION_STRING]")); } }
  • 14. ASP.NET Core et Behavior testing new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .ConfigureServices(s => s.AddSingleton<IStartupConfigurationService, StartupConfigurationService>()) .Build() .Run(); Exemple – Program.Main() :
  • 15. ASP.NET Core et Behavior testing public class Startup { private IStartupConfigurationService externalStartupConfiguration; public Startup(IHostingEnvironment env, IStartupConfigurationService externalStartupConfiguration) { this.externalStartupConfiguration = externalStartupConfiguration; this.externalStartupConfiguration.ConfigureEnvironment(env); … } public void ConfigureServices(IServiceCollection services) { … this.externalStartupConfiguration.ConfigureServices(services, Configuration); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { this.externalStartupConfiguration.Configure(app, env, loggerFactory, Configuration); … } } Exemple – Startup :
  • 16. ASP.NET Core et Behavior testing Exemple – TestMethod : [TestMethod] public void TestScenario() { Data[] data = CreateTestScenarioDataIntoInMemoryDb(); var webHostBuilder = new WebHostBuilder(); webHostBuilder.ConfigureServices( s => s.AddSingleton<IStartupConfigurationService, TestStartupConfigurationService<DbContext>> ()); webHostBuilder.UseStartup<Startup>(); var testServer = new TestServer(webHostBuilder); var response = testServer.CreateClient().GetAsync("/api/data").Result; response.EnsureSuccessStatusCode(); var result = response.Content.ReadAsAsync<Data[]>().Result; Assert.AreEqual(data.Length, result.Length); for (int i = 0; i < data.Length; i++) { Assert.AreEqual(data[i], result[i]); } }
  • 17. ASP.NET Core et Behavior testing SpecFlow • Description naturelle d’un scénario • Abstraction du contexte technique • Semi-intégration à NET Core 2.0
  • 18. ASP.NET Core et Behavior testing Feature: Get blogs In order to list blogs I want to get the list of blogs Background: Given A configured environment Scenario: Get blogs should be ok Given the following blogs | Url | | http://blog1.io | | http://blog2.io | When I get the list of blogs from Api Then the result must be the following list | Url | | http://blog1.io | | http://blog2.io | [Binding] public class MainSteps { [Given(@"A configured environment")] public void GivenAWorkingEnvironment() {} [Given(@"the following blogs")] public void GivenTheFollowingBlogs(Table table) {} [When(@"I get the list of blogs from Api")] public void WhenIGetTheListOfBlogs() {} [Then(@"the result must be the following list")] public void ThenTheResultMustBeTheFollowingList(Table expectedResult) {} } SpecFlow
  • 19. ASP.NET Core et Behavior testing Aller plus loin – Test de la stack MVC • Gestion du ViewModel • Gestion de l’Anti Forgery Token • Gestion des dépendances Razor (.deps.json)
  • 20. ASP.NET Core et Behavior testing Aller plus loin – Gestion de l’identité • Développement de son propre AuthenticationScheme  AuthenticationSchemeOptions  Définition des informations de l’identité de test  AuthenticationHandler<SchemeOptions>  Création de l’identité de test  AuthenticationBuilder  Création du schéma d’authentification à partir des options et du handler
  • 21. ASP.NET Core et Behavior testing • Série d’article sur les tests comportementaux avec ASP.NET Core  http://geeklearning.io/a-different-approach-to-test-your-asp-net-core- application/ • Projet GitHub  https://github.com/geeklearningio/Testavior • Packages nuget  https://www.nuget.org/packages/GeekLearning.Testavior  https://www.nuget.org/packages/GeekLearning.Testavior.Configuration

Notes de l'éditeur

  • #6: Moreover, in this case your tests are very dependent of the implementation details so if a detail has changed, you are likely to have to update the tests as well. Doing so is costly and might also lead to new defects.
  • #11: Webhostbuilder: configure et instantie un hote web responsable de démarrer l’application et de gérer son cycle de vie Startup: configure les services et la request pipeline
  • #20: Anti Forgery Token vise à protéger les users des attaques de type CSRF (Cross Site Request Forgery). Un attaquant envoie un mail à une victime contenant un lien vers un formulaire web d’un site malicieux. Le formulaire est configure pour un POST sur le site vulnerable, les données seraient donc envoyées sur le site vulnerable avec les autorisations de la victime. Pour se protéger, lors du GET du form, le serveur inclu 2 tokens, 1 dans un cookie et l’autre comme input hidden dans le formulaire. Si le client n’envoie pas les 2 tokens, la requête est invalidée. Cela fonctionne car le site malicieux ne peut pas lire le token renvoyé par le serveur grâce à la politique de sécurité de l’origine identique. Le site attaquant peut envoyer un POST mais pas lire la réponse. The Razor engine uses dependency files (.deps.json) to resolve some references at runtime. So in order to test the MVC part of a application, it is necessary to import these files. To do it, add the following section to your .csproj