Multiple vs single asserts per test in selenium?

Viewed 229

I'm creating automated smoke tests. I've read that is not a good practice to use more than one assert on Unit tests, is this rule also applied to webdriver tests with selenium?

On my smoke tests sometimes i use more than 20 asserts to verify that some information like section titles, column titles and other text that should appear are shown correct.

Would it be better to separate assert as different tests or is it ok to have multiple asserts in a single test? If i separate in differents tests the run time will increase a lot.

Here is an example of the code:

if self.claimSummaryPage.check_if_claim_exists():
            assert self.claimSummaryPage.return_claim_summary_mosaic_text() == 'RESUMEN'
            assert self.claimSummaryPage.return_claim_notes_mosaic_text() == 'NOTAS'
            assert self.claimSummaryPage.return_claim_documents_mosaic_text() == 'DOCUMENTOS'
            assert self.claimSummaryPage.return_claim_payments_mosaic_text() == 'PAGOS'
            assert self.claimSummaryPage.return_claim_services_mosaic_text() == 'SERVICIOS'
            assert "Detalles del siniestro: " + claim_number in self.claimSummaryPage.return_claim_title_text()
            assert self.claimSummaryPage.return_claim_status_text() in self.claimSummaryPage.CLAIM_STATUS
            self.claimSummaryPage.check_claim_back_button_exists()
            assert self.claimSummaryPage.return_claim_date_of_loss_title() == 'Fecha y hora'
            assert self.claimSummaryPage.return_claim_reported_by_title() == 'Denunciante'
            assert self.claimSummaryPage.return_claim_loss_location_title() == 'Lugar'
            assert self.claimSummaryPage.return_claim_how_reported_title() == 'Reportado en'
            assert self.claimSummaryPage.return_claim_what_happened_title() == '¿Qué sucedió?'
            assert self.claimSummaryPage.return_claim_adjuster_title() == 'Tramitadores'
            assert self.claimSummaryPage.return_claim_parties_involved_title() == 'Partes implicadas'
            if self.claimSummaryPage.check_if_claim_has_exposures():
                assert self.claimSummaryPage.return_claim_adjuster_table_name_column_title() == 'Nombre'
                assert self.claimSummaryPage.return_claim_adjuster_table_segment_column_title() == 'Segmento'
                assert self.claimSummaryPage.return_claim_adjuster_table_incident_column_title() == 'Incidente'
                assert self.claimSummaryPage.return_claim_adjuster_table_state_column_title() == 'Estado'
            else:
                assert self.claimSummaryPage.return_claim_adjuster_table_no_exposures_label_text() == 'No se encontraron exposiciones'

            if self.claimSummaryPage.return_claim_lob(claim_number) == "AUTO":
                assert self.claimSummaryPageAuto.return_claim_loss_cause() in self.claimSummaryPageAuto.CLAIM_AUTO_LOSS_CAUSE
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_title() == 'Vehículos involucrados'
                self.claimSummaryPageAuto.verify_claim_has_involved_vehicles()
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_make_column_title() == 'Marca'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_model_column_title() == 'Modelo'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_year_column_title() == 'Año'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_license_column_title() == 'Patente'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_loss_party_column_title() == 'Parte vinculada'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_damage_column_title() == 'Daños'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_damage_type_column_title() == 'Tipo de daño'
                assert self.claimSummaryPageAuto.return_claim_involved_vehicles_table_first_item_loss_party_text() in self.claimSummaryPageAuto.VEHICLE_LOSS_PARTY
3 Answers

Given that gui tests take much more time it would probably not be efficient to just have one assert in each test. The best would probably be to have a test suite where in which you execute one assert per test during the same run. I've also had experience where we implemented our own assert methods for the gui tests which caches the results from all asserts in the gui tests and goes through them in the end and fails the test if any of the cached assertions failed. This is due to the nature of the system we worked with at the time. Maybe this could be a way to solve it for you?

This works given that the assertions you do are not on anything that would cause an error if you continue even if the assertion fails, e.g. if a step in a process would fail.

Example:

my_assertion_cache = list()

def assert_equals(a, b):
    try:
        assert a == b
    except AssertionError:
        # preferably add a reference to the locator where this failed into the message below
        my_assertion_cache.append(f"{a} and {b} was expected to be equal")


def run_after_each_test():
    assert mylist == []

Tests should test the system and user behavior not just the assertion .

you can change your tests as ("generic example") :

let user and summarypage be the pageobjects so:

summary class:

class summary(){

public static expectedDetails = ["something1", "something2"]
function getDetails(){
   return [self.claimSummaryPage.return_claim_payments_mosaic_text()]
}

}

now your test:

test("validate user can successfully login and vie claim summary"){   
   user.userlogins()
   details = summary.getDetails()
   assert(details).to.be.equal(summary.expectedDetails)   
}

here instead of individually validaiting each string , we are saving to an array and comparing the resulting array and expected array

This is much cleaner approach. Don't add assertion in pageobject

Generaly if your first assert fails, then others will not be executed in case where you have multiple assertions in one test.

On the other hand If you do not perform any new action in your test, like you are on page and you are checking some UI and do not perform any click, or select, or any new action, you can use multiple assertions.

Remember Auto test are used so you dont need to run tests manualy, and they can identify problem faster, and with more precision.This is why recomendation goes to the one assertion, one test.

So the question can be translated like this: Do I want to identify only one issue, or all possible issues with the auto tests?

Related