Programmatic email in C# (test email APIs in .NET Core and ASP.NET)
Tags: csharp, testing, tutorial, dotnet
Published: 2020-05-01 19:50:16

Selenium is a common integration test framework popular with C# developers. With the MailSlurp DotNet SDK you can send and receive emails from code and tests.

![welcome](https://www.mailslurp.com/assets/screenshots/firefox-selenium-dotnet.png)

If you write .NET applications you probably deal with email addresses at some point: for user sign-up, email newsletters, password resets and more. If you want to test this functionality end-to-end you need test email accounts. 

MailSlurp is a free API that lets you create email addresses in C# then send and receive emails with them. This article will show you how to test a web applications user sign-up using Nunit, .NET Core 2.1, Selenium and Firefox Gecko Driver.

## Example application
For an example of using emails in selenium with .NET we will use a dummy web app hosted at [https://playground.mailslurp.com](https://playground.mailslurp.com). 

![selenium email example](https://www.mailslurp.com/assets/screenshots/selenium/s1.png)

This app has a real sign-up process. It lets users sign-up with an email address, then it sends them a confirmation code via email. The user can then submit the confirmation code and confirm their account. Finally the user can sign in and see a welcome screen.

We'll test this process end to end. Full [source code available on GitHub](https://github.com/mailslurp/examples/).

## Writing a test
To test the Playgrounds authentication process with real email addresses lets set up a .NET Core 2.1 project. 

::: tip
MailSlurp's CSharp Package [on NuGet](https://www.nuget.org/packages/mailslurp/) supports .Net Core 2.x and 3.x. If You need another target consider the [REST API](/docs/api/).
:::

### Setup 
First you need Firefox and the Selenium Gecko Driver. You can install them with `choco` or download them manually and add them to your Path.

```bash
choco install firefox
choco install selenium-gecko-driver
```

### Add project dependencies
Create a new .NET Core project and add the following dependencies in `YourProject.csproj`:

```xml
  <ItemGroup>
    <PackageReference Include="mailslurp" Version="7.1.3" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
    <PackageReference Include="nunit" Version="3.12.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.16.1">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
    <PackageReference Include="Selenium.WebDriver.GeckoDriver" Version="0.26.0.1" />
  </ItemGroup>
```

### Create test file
Next create an Nunit test:

```csharp
using System;
using System.Text.RegularExpressions;
using mailslurp.Api;
using mailslurp.Client;
using mailslurp.Model;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

// Example usage for MailSlurp email API plugin
namespace ExampleService.Tests
{
    
    [TestFixture]
    public class ExampleTest
    {
        // tests will go here
    }
}
```

Next we need to configure Selenium. We will add a FirefoxDriver and tell it to start before our tests. Then we'll add a shutdown method after the tests have finished. Put the following inside the `ExampleTest` class:

```csharp
private static IWebDriver _webdriver;
private static Configuration _mailslurpConfig;

// get a MailSlurp API Key free at https://app.mailslurp.com
private static readonly string YourApiKey = "your-api-key-here";

private static readonly long TimeoutMillis = 30_000L;

[SetUpFixture]
public class NunitSetup
{
    // runs once before any tests
    [OneTimeSetUp]
    public void SetUp()
    {
        // set up the webdriver for selenium
        var timeout = TimeSpan.FromMilliseconds(TimeoutMillis);
        var service = FirefoxDriverService.CreateDefaultService()
        _webdriver = new FirefoxDriver(service, new FirefoxOptions(), timeout);
        _webdriver.Manage().Timeouts().ImplicitWait = timeout;
        
        // configure mailslurp with API Key
        Assert.NotNull(YourApiKey);
        _mailslurpConfig = new Configuration();
        _mailslurpConfig.ApiKey.Add("x-api-key", YourApiKey);
    }

    // runs once after all tests finished
    [OneTimeTearDown]
    public void Dispose()
    {
        // close down the browser
        _webdriver.Quit();
        _webdriver.Dispose();
    }
}
```

### Test loading the playground
Now we can write some tests. So let's load the playground app and click the sign-up button:

```csharp
[Test, Order(1)]
public void CanLoadPlaygroundAppInBrowser_AndClickSignUp()
{
    // open the dummy authentication app and assert it is loaded
    _webdriver.Navigate().GoToUrl("https://playground.mailslurp.com");
    Assert.AreEqual("React App", _webdriver.Title);
    
    // can click the signup button
    _webdriver.FindElement(By.CssSelector("[data-test=sign-in-create-account-link]")).Click();
}
```

### Create test email accounts
Next we need to start a user sign-up. We will need a new test email account first. Create one with MailSlurp then use it to fill the sign-up form:

```csharp
private static Inbox _inbox;

[Test, Order(2)]
public void CanCreateTestEmail_AndStartSignUp()
{
    // first create a test email account
    var inboxControllerApi = new InboxControllerApi(_mailslurpConfig);
    _inbox = inboxControllerApi.CreateInbox();
    
    // inbox has a real email address
    var emailAddress = _inbox.EmailAddress;
    
    // next fill out the sign-up form with email address and a password
    _webdriver.FindElement(By.Name("email")).SendKeys(emailAddress);
    _webdriver.FindElement(By.Name("password")).SendKeys(Password);
    
    // submit form
    _webdriver.FindElement(By.CssSelector("[data-test=sign-up-create-account-button]")).Click();
}
```

If we run the test the result should look like this:

![selenium email example](https://www.mailslurp.com/assets/screenshots/selenium/s2.png)

### Receive confirmation email
Once the sign-up form is submitted the playground app will send a confirmation code to the email address. We can wait for the email to arrive using MailSlurp.

```csharp
private static Email _email;

[Test, Order(3)]
public void CanReceiveConfirmationEmail()
{
    // now fetch the email that playground sends us
    var waitForControllerApi = new WaitForControllerApi(_mailslurpConfig);
    _email = waitForControllerApi.WaitForLatestEmail(inboxId: _inbox.Id, timeout: TimeoutMillis, unreadOnly: true);

    // verify the contents
    Assert.IsTrue(_email.Subject.Contains("Please confirm your email address"));
}
```

### Extract content and confirm
Next let's find the verification code in the email and submit it to the confirmation screen:

```csharp
private static String _confirmationCode;

[Test, Order(4)]
public void CanExtractConfirmationCode()
{
    // we need to get the confirmation code from the email
    var rx = new Regex(@".*verification code is (\d{6}).*", RegexOptions.Compiled);
    var match = rx.Match(_email.Body);
    _confirmationCode = match.Groups[1].Value;
    
    Assert.AreEqual(6, _confirmationCode.Length);
}

[Test, Order(5)]
public void CanConfirmUserWithEmailedCode()
{
    // fill the confirm user form with the confirmation code we got from the email
    _webdriver.FindElement(By.Name("code")).SendKeys(_confirmationCode);
    _webdriver.FindElement(By.CssSelector("[data-test=confirm-sign-up-confirm-button]")).Click();
}
```

Running the test should look as follows:

![selenium email example](https://www.mailslurp.com/assets/screenshots/selenium/s3.png)

### Sign in with confirmed user
Finally we can test that a confirmed user can sign in. Load the playground again and sign in.

```csharp
[Test, Order(6)]
public void CanLoginWithConfirmedUser()
{
    // load the main page again
    _webdriver.Navigate().GoToUrl("https://playground.mailslurp.com");
    
    // login with email and password (we expect it to work now that we are confirmed)
    _webdriver.FindElement(By.Name("username")).SendKeys(_inbox.EmailAddress);
    _webdriver.FindElement(By.Name("password")).SendKeys(Password);
    _webdriver.FindElement(By.CssSelector("[data-test=sign-in-sign-in-button]")).Click();

    // verify that user can see authenticated content
    Assert.IsTrue(_webdriver.FindElement(By.TagName("h1")).Text.Contains("Welcome"));
}
```

The login should look like this:

![selenium email example](https://www.mailslurp.com/assets/screenshots/selenium/s4.png)

Once logged in the user will be greeted with a welcome message.

![selenium email example](https://www.mailslurp.com/assets/screenshots/playground/welcome.png)

## Next steps
Selenium is a powerful testing tool. When combined with test email accounts you can test email related processes end-to-end. MailSlurp is free email API with C# bindings. Check out the [documentation to get started](/docs/csharp/).