Skip to content

Commit

Permalink
Merge branch 'master' into 3644
Browse files Browse the repository at this point in the history
  • Loading branch information
EDbarvinsky committed Mar 30, 2023
2 parents bde2082 + 60d00df commit 1a019d6
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -138,9 +138,9 @@ private void scanScreenshot(BufferedImage screenshot, Set<VariableScope> scopes,
}
catch (NotFoundException e)
{
softAssert.recordFailedAssertion(notFoundMessage, e);
Attachment attachment = new Attachment(ImageTool.toByteArray(screenshot), "Screenshot", "image/png");
eventBus.post(new AttachmentPublishEvent(attachment));
softAssert.recordFailedAssertion(notFoundMessage, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
Expand Down Expand Up @@ -91,8 +92,7 @@ void whenIScanBarcodeAndBarcodeIsAbsent() throws IOException, NotFoundException

barCodeSteps.scanBarcode(VARIABLE_SCOPE, VARIABLE_NAME);

verify(softAssert).recordFailedAssertion("There is no barcode on the screen", exception);
verifyScreenshotAttachment();
verifyScreenshotNotFoundBehavior("There is no barcode on the screen", exception);
}

@Test
Expand All @@ -119,9 +119,7 @@ void whenIScanBarcodeFromSearchContextAndBarcodeIsAbsent() throws IOException, N
var exception = NotFoundException.getNotFoundInstance();
when(barcodeActions.scanBarcode(QR_CODE_IMAGE)).thenThrow(exception);
barCodeSteps.scanBarcodeFromContext(VARIABLE_SCOPE, VARIABLE_NAME);
verify(softAssert).recordFailedAssertion("There is no barcode on the selected context, page or screen",
exception);
verifyScreenshotAttachment();
verifyScreenshotNotFoundBehavior("There is no barcode on the selected context, page or screen", exception);
}

private void mockScreenshotFromSearchContext()
Expand All @@ -133,16 +131,18 @@ private void mockScreenshotFromSearchContext()
when(screenshot.getImage()).thenReturn(QR_CODE_IMAGE);
}

private void verifyScreenshotAttachment() throws IOException
private void verifyScreenshotNotFoundBehavior(String assertionMessage, Exception exception) throws IOException
{
var ordered = inOrder(eventBus, softAssert);
var eventCaptor = ArgumentCaptor.forClass(Object.class);
verify(eventBus).post(eventCaptor.capture());
ordered.verify(eventBus).post(eventCaptor.capture());
Object event = eventCaptor.getValue();
assertThat(event, instanceOf(AttachmentPublishEvent.class));
Attachment attachment = ((AttachmentPublishEvent) event).getAttachment();
assertEquals("Screenshot", attachment.getTitle());
assertEquals("image/png", attachment.getContentType());
assertArrayEquals(ImageTool.toByteArray(QR_CODE_IMAGE), attachment.getContent());
ordered.verify(softAssert).recordFailedAssertion(assertionMessage, exception);
verifyNoInteractions(variableContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -318,11 +319,16 @@ private void verifyComparisonResult(DataSetComparisonRule comparisonRule, DataSo
{
attachmentPublisher.publishAttachment("data-sources-statistics.ftl", Map.of("statistics", dataSourceStatistics),
"Data sources statistics");
if (!softAssert.assertTrue(comparisonRule.getAssertionDescription(), result.isEmpty()))

Consumer<Boolean> resultConsumer = passed ->
{
attachmentPublisher.publishAttachment("/templates/maps-comparison-table.ftl", Map.of("results", result),
"Data sets comparison");
}
if (!passed)
{
attachmentPublisher.publishAttachment("/templates/maps-comparison-table.ftl", Map.of("results", result),
"Data sets comparison");
}
};
softAssert.assertTrue(comparisonRule.getAssertionDescription(), result.isEmpty(), resultConsumer);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.stream.Stream;

import com.github.valfirst.slf4jtest.TestLogger;
Expand Down Expand Up @@ -297,7 +298,7 @@ void shouldCompareQueriesResponsesAndPostDiffTable() throws InterruptedException
List<Map<String, Object>> result = List.of(Map.of(COL1, VAL1), Map.of(COL1, VAL1), Map.of(COL1, VAL3));
mockQueryForList(QUERY, DB_KEY, result);
mockQueryForList(QUERY2, DB_KEY2, List.of(Map.of(COL1, VAL2)));
when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, false)).thenReturn(false);
doAnswer(getAssertionAnswer(false)).when(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(false), any());
mockHashing();
configureTimeout();
databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.DISTINCT);
Expand Down Expand Up @@ -351,7 +352,7 @@ void shouldLimitDiffTable() throws InterruptedException, ExecutionException, Tim
List<Map<String, Object>> result = List.of(Map.of(COL1, VAL1), Map.of(COL1, VAL3));
mockQueryForList(QUERY, DB_KEY, result);
mockQueryForList(QUERY, DB_KEY2, List.of(Map.of(COL1, VAL2)));
when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, false)).thenReturn(false);
doAnswer(getAssertionAnswer(false)).when(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(false), any());
mockHashing();
configureTimeout();
databaseSteps.compareData(QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, QUERY, DB_KEY2, KEYS);
Expand Down Expand Up @@ -453,7 +454,8 @@ static Stream<Arguments> notMatchingDataSets()
void shouldCompareDataVsExamplesTableAndPostReportFailedChecks(DataSetComparisonRule comparisonRule,
List<Map<String, Object>> leftDataSet, List<Map<String, String>> rightDataSet)
{
when(softAssert.assertTrue(comparisonRule.getAssertionDescription(), false)).thenReturn(false);
doAnswer(getAssertionAnswer(false)).when(softAssert).assertTrue(eq(comparisonRule.getAssertionDescription()),
eq(false), any());
databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP);
mockHashing();
mockDataSource();
Expand Down Expand Up @@ -508,11 +510,11 @@ void testWaitUntilQueryReturnedDataEqualToTable()
{
databaseSteps.setDuplicateKeysStrategy(DuplicateKeysStrategy.NOOP);
mockQueryForList(QUERY, DB_KEY, List.of(Map.of(COL1, VAL2)));
when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true);
doAnswer(getAssertionAnswer(true)).when(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(true), any());
databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, TABLE);
verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL),
any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE));
verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, true);
verify(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(true), any());
}

@Test
Expand All @@ -529,11 +531,11 @@ void testWaitTwiceUntilQueryReturnedDataEqualToTable()
.thenReturn(List.of(Map.of(COL1, VAL1)))
.thenReturn(List.of(Map.of(COL1, VAL2)));

when(softAssert.assertTrue(QUERY_RESULTS_ARE_EQUAL, true)).thenReturn(true);
doAnswer(getAssertionAnswer(true)).when(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(true), any());
databaseSteps.waitForDataAppearance(TWO_SECONDS, 10, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO, TABLE);
verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL),
any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE));
verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, true);
verify(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(true), any());
}

@Test
Expand All @@ -549,14 +551,15 @@ void testWaitUntilQueryReturnedDataEqualToTableFailed()
when(jdbcTemplate.queryForList(QUERY))
.thenReturn(List.of(Map.of(COL1, VAL1)))
.thenReturn(List.of(Map.of(COL1, VAL3)));
doAnswer(getAssertionAnswer(false)).when(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(false), any());

databaseSteps.waitForDataAppearance(Duration.ofSeconds(4), 2, QUERY, DB_KEY, DataSetComparisonRule.IS_EQUAL_TO,
TABLE);
String logMessage = "SQL result data is not equal to expected data in {} records";
assertThat(LOGGER.getLoggingEvents(), equalTo(List.of(info(logMessage, 1), info(logMessage, 1))));
verify(attachmentPublisher).publishAttachment(eq(DATA_SOURCES_STATISTICS_FTL),
any(Map.class), eq(DATA_SOURCES_STATISTICS_TITLE));
verify(softAssert).assertTrue(QUERY_RESULTS_ARE_EQUAL, false);
verify(softAssert).assertTrue(eq(QUERY_RESULTS_ARE_EQUAL), eq(false), any());
verify(attachmentPublisher).publishAttachment(eq(DATA_SET_COMPARISON_FTL), argThat(r -> {
@SuppressWarnings("unchecked")
List<List<EntryComparisonResult>> results = (List<List<EntryComparisonResult>>) ((Map<?, ?>) r)
Expand Down Expand Up @@ -650,4 +653,14 @@ private void configureTimeout()
{
databaseSteps.setDbQueryTimeout(Duration.ofSeconds(20));
}

private Answer getAssertionAnswer(boolean assertionPassed)
{
return a ->
{
Consumer<Boolean> consumer = a.getArgument(2);
consumer.accept(assertionPassed);
return null;
};
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package org.vividus.softassert;

import java.util.function.Consumer;
import java.util.regex.Pattern;

import org.hamcrest.Matcher;
Expand All @@ -31,6 +32,17 @@ public interface ISoftAssert
*/
boolean assertTrue(String description, boolean condition);

/**
* Asserts that a condition is true. If it isn't, an assertion error is added to the collection.
* An additional operation which will always be executed is specified.
* Useful when used with fail-fast at the scenario level.
* @param description The assertion description
* @param condition Condition to be checked
* @param resultConsumer Always executed additional operation that consumes result of the assertion
* @return <code>true</code> if assertion is passed, otherwise <code>false</code>
*/
boolean assertTrue(String description, boolean condition, Consumer<Boolean> resultConsumer);

/**
* Asserts that a condition is false. If it isn't an assertion error is added to the collection.
* @param description The assertion description
Expand Down Expand Up @@ -167,6 +179,22 @@ public interface ISoftAssert
*/
<T> boolean assertThat(String description, T actual, Matcher<? super T> matcher);

/**
* Asserts that <code>actual</code> satisfies the condition specified by <code>matcher</code>.
* If it is not, an assertion error is added to the collection.
* An additional operation which will always be executed is specified.
* Useful when used with fail-fast at the scenario level.
* @param description The assertion description
* @param <T> the static type accepted by the matcher (this can flag obvious
* compile-time problems such as {@code assertThat(1, is("a"))}
* @param actual the computed value being compared
* @param matcher an expression, built of {@link Matcher}s, specifying allowed
* values
* @param resultConsumer always executed additional operation that consumes result of the assertion
* @return <code>true</code> if assertion is passed, otherwise <code>false</code>
*/
<T> boolean assertThat(String description, T actual, Matcher<? super T> matcher, Consumer<Boolean> resultConsumer);

/**
* Logs information about passed assertion and returns true.
* @param description The assertion description
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.vividus.softassert;

import java.util.List;
import java.util.function.Consumer;
import java.util.regex.Pattern;

import com.google.common.eventbus.EventBus;
Expand Down Expand Up @@ -67,7 +68,13 @@ public class SoftAssert implements ISoftAssert
@Override
public boolean assertTrue(final String description, final boolean condition)
{
return recordAssertion(condition, description, condition ? IS_TRUE : IS_FALSE);
return assertTrue(description, condition, null);
}

@Override
public boolean assertTrue(String description, boolean condition, Consumer<Boolean> resultConsumer)
{
return recordAssertionWithFinally(condition, description, condition ? IS_TRUE : IS_FALSE, resultConsumer);
}

@Override
Expand Down Expand Up @@ -206,10 +213,17 @@ public boolean assertNull(String description, final Object object)

@Override
public <T> boolean assertThat(String description, T actual, Matcher<? super T> matcher)
{
return assertThat(description, actual, matcher, null);
}

@Override
public <T> boolean assertThat(String description, T actual, Matcher<? super T> matcher,
Consumer<Boolean> resultConsumer)
{
boolean matches = matcher.matches(actual);
String matcherDescriptionString = getAssertionDescriptionString(actual, matcher);
return recordAssertion(matches, description, matcherDescriptionString);
return recordAssertionWithFinally(matches, description, matcherDescriptionString, resultConsumer);
}

protected String getNullAssertionDescription(final Object object)
Expand Down Expand Up @@ -313,6 +327,22 @@ private boolean recordAssertion(boolean passed, String description, String asser
return recordAssertion(passed, format(description, assertionDescription));
}

private boolean recordAssertionWithFinally(boolean passed, String description, String assertionDescription,
Consumer<Boolean> resultConsumer)
{
try
{
return recordAssertion(passed, format(description, assertionDescription));
}
finally
{
if (resultConsumer != null)
{
resultConsumer.accept(passed);
}
}
}

private boolean recordAssertion(boolean passed, String description, Throwable cause)
{
if (passed)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,6 +28,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
Expand All @@ -36,6 +37,7 @@
import static uk.org.lidalia.slf4jext.Level.ERROR;

import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -189,6 +191,15 @@ void testAssertTrueNot()
assertFalse(softAssert.assertTrue(TRUE, TEXT.equals(EMPTY_STRING)));
}

@Test
void testAssertTrueWithConsumer()
{
mockAssertionCollection();
Consumer<Boolean> consumer = mock();
assertTrue(softAssert.assertTrue(TRUE, TEXT.equals(TEXT), consumer));
verify(consumer).accept(true);
}

@Test
void testAssertNotNull()
{
Expand Down Expand Up @@ -234,6 +245,18 @@ void testAssertThatFalse()
assertFalse(softAssert.assertThat("Text contains 'a'", TEXT, containsString("a")));
}

@Test
void testAssertThatWithConsumerAndException()
{
mockAssertionCollection();
Consumer<Boolean> consumer = mock();
when(failTestFastManager.isFailTestCaseFast()).thenReturn(true);
doThrow(RuntimeException.class).when(failTestFastHandler).failTestCaseFast();
assertThrows(RuntimeException.class,
() -> softAssert.assertThat("Text contains 'b'", TEXT, containsString("b"), consumer));
verify(consumer).accept(false);
}

@Test
void testRecordFailedAssertion()
{
Expand Down
Loading

0 comments on commit 1a019d6

Please sign in to comment.