Orientação gerada a partir de informações públicas. Apenas para referência.
Shouldly é uma biblioteca de asserção no estilo BDD para Dart e Flutter que prioriza mensagens de erro claras e descritivas quando os testes falham. Projetada para melhorar a legibilidade dos testes e a eficiência na depuração, oferece uma API fluida que se parece com linguagem natural. A biblioteca é extensível, permitindo que os desenvolvedores personalizem as asserções conforme as necessidades específicas do projeto. Suporta todas as principais plataformas, incluindo Android, iOS, Web, macOS, Windows e Linux, tornando-a ideal para fluxos de trabalho de teste cruzado.
Casos de uso
Escrever testes unitários legíveis e mantidos
Melhorando o diagnóstico de falhas de teste
Melhorando fluxos de trabalho de desenvolvimento orientado a testes
Testes multiplataforma com afirmações consistentes
Personalizando a lógica de afirmação para validação específica do domínio
Principais recursos
Sintaxe de afirmação fluente e legível
Mensagens de erro detalhadas e úteis em caso de falha
Sistema de afirmação extensível
Suporta todas as plataformas do Flutter
API intuitiva com estilo BDD
Integração fácil por meio do pub add
Indicado para
Desenvolvedores que buscam melhor feedback de teste
Equipes praticando TDD ou BDD
Projetos que exigem saída de teste clara
Aplicações Flutter multiplataforma
Engenheiros de automação de testes
Considerações
Pode exigir curva de aprendizado para novos usuários do BDD
Dependência adicional em conjuntos de testes
Limitado ao contexto de teste (não para uso em tempo de execução)
Não adequado para afirmações de código de produção
Requer configuração cuidadosa para afirmações personalizadas
README original
Snapshot do README original do repositório-fonte vinculado. Consulte o repositório para o conteúdo mais recente.
shouldly is an assertion concept that focuses on
writing assertions as plain English sentences
and giving better error messages when the assertion fails while being simple and terse.
satisfyAllConditions will show all errors at once, not only first fail assertion.
test('should satisfy all conditions', () {
Should.satisfyAllConditions([
() => playerCharacter.nickname.should.as('nickname').not.beNullOrEmpty(),
() => playerCharacter.weapons.should.as('weapons').contain('Staff of Wonder'),
() => playerCharacter.health.should.as('health').be(100),
]);
});
Example report can be:
Expected satisfy all conditions specified, but does not.
The following errors were found ...
------------- Error 1 -------------
Expected nickname
should not be null or empty
but was
''
------------- Error 2 -------------
Expected weapons
should contain
Staff of Wonder
but was actually
[Axe, Sword]
------------- Error 3 -------------
Expected health
should be
100
but was
99
------------------------------------
Custom matchers
For existing one - just create an extension for it
extensionCustomNumAssertionsonNumericAssertions {
NumericAssertionsget beNegative {
if (subject >= 0) {
throwShouldlyTestFailureError('Number\n should be negative');
}
returnNumericAssertions(subject);
}
}
Or more exotic matchers - fot custom types
First, create a Assertions class for your custom type which extends BaseAssertions
classCustomerAssertionsextendsBaseAssertions<Customer, CustomerAssertions> {
// ...CustomerAssertionsget beMarried {
if (isReversed) {
if (subject!.isMarried) {
throwShouldlyTestFailureError('Customer should not be married');
}
} else {
if (!subject!.isMarried) {
throwShouldlyTestFailureError('Customer should be married');
}
}
returnCustomerAssertions(subject);
}
CustomerAssertionsget beMale {
if (isReversed) {
Execute.assertion
.forCondition(subject!.gender == Gender.male)
.failWith('$subjectLabel should not be male');
} else {
Execute.assertion
.forCondition(subject!.gender != Gender.male)
.failWith('$subjectLabel should be male');
}
Execute.assertion
.forCondition(subject!.gender != Gender.male)
.failWith('$subjectLabel should be male');
returnCustomerAssertions(subject);
}
// ...
}
Second, create an extension on your class which has should property with type of your custom assertions class
extensionCustomerExtensiononCustomer {
CustomerAssertionsget should => CustomerAssertions(this);
}
Third, you are ready to go use your own shouldly assertions
test('async function should throw exception', () async {
awaitShould.throwAsync(() {
Future.delayed(Duration(milliseconds: 100));
throwException('test');
});
});
test('async function should throw exact exception', () async {
awaitShould.throwAsync<CustomException>(() {
Future.delayed(Duration(milliseconds: 100));
throwCustomException('custom exception test');
});
});
test('should complete in a duration', () async {
awaitShould.completeIn(
Duration(seconds: 1),
func: () => slowFunction(
Duration(milliseconds: 900),
),
);
});
Enums
test('should not be equal', () {
seasons.spring.should.not.be(seasons.winter);
});
test('should not be type of', () {
seasons.spring.should.not.beOfType<level>();
});
test('should be assignable to `Enum`', () {
seasons.spring.should.beAssignableTo<Enum>();
});
extensionCustomerExtensiononCustomer {
CustomerAssertionsget should => CustomerAssertions(this);
}
classCustomerAssertionsextendsBaseAssertions<Customer, CustomerAssertions> {
CustomerAssertions(
Customer? subject, {
bool isReversed = false,
String? subjectLabel,
}) : super(subject, isReversed: isReversed, subjectLabel: subjectLabel);
CustomerAssertionsget beMarried {
if (isReversed) {
if (subject!.isMarried) {
throwShouldlyTestFailure('Customer should not be married');
}
} else {
if (!subject!.isMarried) {
throwShouldlyTestFailure('Customer should be married');
}
}
returnCustomerAssertions(subject);
}
CustomerAssertionsget beMale {
if (isReversed) {
if (subject!.gender == Gender.male) {
throwShouldlyTestFailure('Customer should be female');
}
} else {
if (subject!.gender != Gender.male) {
throwShouldlyTestFailure('Customer should be male');
}
}
returnCustomerAssertions(subject);
}
@overrideCustomerAssertionscopy(
Customer? subject, {
bool isReversed = false,
String? subjectLabel,
}) =>
CustomerAssertions(
subject,
isReversed: isReversed,
subjectLabel: subjectLabel,
);
}
Recommendations
You can improve the readability of the rest of your test code with given_when_then_unit_test, which enhances the test report readability as well.
Changelog
Please see the Changelog page to know what's recently changed.
Contributing
Feel free to contribute to this project.
If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.
If you fixed a bug or implemented a new feature, please send a pull request.