Запуск всех тестов одновременно приводит к сбою некоторых из них, но когда они запускаются в одиночку, то они работают нормально - PullRequest
1 голос
/ 18 июня 2019

У меня есть какая-то странная проблема, что некоторые мои тесты не выполняются каждый раз, когда я Run all проверяю, но когда я запускаю их 1 на 1, тогда все работает нормально

вот код, который не срабатывает при заполнении InMemoryDatabase

Он должен добавить несколько Permission s к таблице Permissions и затем создать Group s, которые имеют отношение "многие ко многим" к разрешениям

Обычно одна группа может иметь много разрешений, и одно разрешение может использоваться во многих группах

Но проблема в том, что

.Single бросков

Последовательность содержит более одного элемента

когда все тесты выполняются одновременно, но все в порядке, когда он выполняется один

Есть идеи?

public class Tests : IDisposable
{
    private readonly Context _context;

    public void Dispose()
    {
        _context.Database.EnsureDeleted();
    }

    public Tests()
    {
        var o = new DbContextOptionsBuilder<Context>();
        o.UseInMemoryDatabase("testDb");
        _context = new Context(o.Options);
        _context.Database.EnsureDeleted();
        _context.Database.EnsureCreated();
    }

    [Fact]

    public async void myTest()
    {
        Initializer.InitializePermissions(_context);
        Initializer.InitializeGroups(_context);
        (...)
    }
}

public static class Initializer
{
    public static void InitializePermissions(Context context)
    {
        var permissionNames = new List<string>
        {
            "CanCreateNewProduct",
            "CanRemoveProduct",
        };

        foreach (var permission in permissionNames)
        {
            context.Permissions.Add(new Permission(permission));
        }

        context.SaveChanges();
    }   

    public static void InitializeGroups(Context context)
    {
        var groups = new Dictionary<string, List<string>>();

        groups.add("Admin", new List<string>{"CanRemoveProduct"};

        foreach (var group in groups)
        {
            foreach (var permissionName in group.Value)
            {
                var permission = context.Permissions.Single(x => x.Name == permissionName);

                group.GroupPermissions.Add
                (
                    new Many2Many
                    {
                        Group = group,
                        GroupId = group.Id,
                        Permission = permission,
                        PermissionId = permission.Id
                    }
                );
            }

            context.Groups.Add(new Group(group.Key, permissions);
        }

        context.SaveChanges();
    }
}

1 Ответ

4 голосов
/ 18 июня 2019

Проблема здесь в том, что ваши тесты используют общее состояние.

(Кстати, если вам когда-нибудь интересно, почему многие программисты пойдут на все, чтобы избежать использования чего-либо static, и вы чувствуете,их объекты, инъекции зависимостей и т. д. слишком сложны, когда они могут просто «сделать его статичным» ... Вот почему.)

Ваш Initializer может , вероятно, останется staticДо тех пор, пока это не поддерживает внутренне состояние.На что это не похоже, по крайней мере, с первого взгляда, поскольку вы передаете ему экземпляр контекста базы данных.Но так как вы продолжаете работать в своей системе, важно убедиться, что этот инициализатор не поддерживает само состояние по всем тестам.

Это затем приводит нас к самой базе данных в памяти:

o.UseInMemoryDatabase("testDb");

Они доступны по всему приложению. Но вы можете дать им уникальные имена.Например:

var dbName = Guid.NewGuid().ToString();
o.UseInMemoryDatabase(dbName);

При этом у каждого контекста БД должна быть уникальная база данных, на которую вы позже сможете ссылаться с dbName везде, где это может понадобиться.Таким образом, несмотря на то, что все базы данных технически доступны во всем мире, любой данный тест знает только о своих собственных и может ссылаться только на свои собственные.

(Конечно, следите за производительностью. Если вы создаете большие сложные базы данных, чего не следует делать для небольших индивидуальных тестов, тогда создание множества этих баз данных может замедлить процесс.)

...