Package: givenpy
GivenPyGivenPy is a super simple yet highly extensible micro testing library to
enable easier behavior driven development in Python.It doesn't require any fancy dependencies and can work with any test execution framework like unittest or pytest.It is basically a syntax sugar that allows you to write tests in a more readable way. It also helps you
to encourage the re-use of setup code (given steps).ExampleimportunittestfromtypingimportDictfromhamcrestimport*fromstarlette.testclientimportTestClientfromtests.givenpyimportgiven,when,thenfromtests.stepsimportprepare_api_server,create_test_client,prepare_injectorclassTestExample(unittest.TestCase):deftest_health_works(self):withgiven([prepare_injector(),# custom code to prepare the test environmentprepare_api_server(),create_test_client(),])ascontext:client:TestClient=context.clientwithwhen():response:Dict=client.get('/api/v1/health').json()withthen():assert_that(response,instance_of(dict))assert_that(response['status'],is_(equal_to('OK')))or simplerimportunittestfromtypingimportDictfromhamcrestimport*fromstarlette.testclientimportTestClientfromtests.givenpyimportgiven,when,thenfromtests.stepsimportprepare_api_server,create_test_client,prepare_injectordeftest_health_works():withgiven([prepare_injector(),# custom code to prepare the test environmentprepare_api_server(),create_test_client(),])ascontext:client:TestClient=context.clientwithwhen():response:Dict=client.get('/api/v1/health').json()withthen():assert_that(response,instance_of(dict))assert_that(response['status'],is_(equal_to('OK')))InstallationpipinstallgivenpyPyHamcrestDocumentationdefmagic_function(x,external_number):returnx+1+external_numberdefthere_is_external_number():context.external_number=1deftest_magic_function():withgiven([there_is_external_number,])ascontext:withwhen("I call the magic function"):result=magic_function(1,context.external_number)withthen():assert_that(result,is_(equal_to(3)))But I recommend using more flexible higher functiosn that can become configurable:defmagic_function(x,external_number):returnx+1+external_numberdefthere_is_external_number(number):defstep(context):context.external_number=numberreturnstepdeftest_magic_function():withgiven([there_is_external_number(5),])ascontext:withwhen("I call the magic function"):result=magic_function(1,context.external_number)withthen("it should return 7"):assert_that(result,is_(equal_to(7)))More examplesThis example is from one of the bigger projects where we use givenpy to test our API endpoints.importloggingimportulidfromhamcrestimport*fromstarlette.testclientimportTestClientfromapp.organizations.repositoryimportTeamRepositoryfromapp.organizations.team.coreimportTeamfromtests.givenpyimportgiven,when,thenfromtests.integration.organization.test_feedback_submissionimportperson_is_presentfromtests.integration.steps_authimportauth_is_readyfromtests.integration.steps_databaseimportdatabase_repo_is_ready,database_is_cleanfromtests.integration.steps_issuesimportthere_is_organizationfromtests.stepsimportprepare_api_server,create_test_client,prepare_injectorlogging.basicConfig(level=logging.DEBUG)deftest_team_creation_for_the_organization_should_work():withgiven([prepare_injector(),database_repo_is_ready(),database_is_clean(),prepare_api_server(),there_is_organization(),create_test_client(),auth_is_ready(),])ascontext:client:TestClient=context.clientorganization_id:ulid.ULID=context.organization_idwithwhen():payload={"command_name":"CreateTeamCommand","entity_type":"team","payload":{"name":"Test Team","organization_id":str(organization_id),"members":[]}}response=client.post(f'/api/v1/organizations/{organization_id}/teams',headers=context.add_token(),json=payload)withthen():assert_that(response.status_code,equal_to(200))team_repo:TeamRepository=context.injector.get(TeamRepository)team=team_repo.find_one(response.json()['id'])assert_that(team.name,equal_to("Test Team"))assert_that(team.organization_id,equal_to(organization_id))defthere_is_team(name="Test Team"):defstep(context):team_repo:TeamRepository=context.injector.get(TeamRepository)team=team_repo.save(Team(name=name,organization_id=context.organization_id,id=ulid.new(),))context.team_id=team.idreturnstepdeftest_i_should_be_able_to_add_the_person_to_a_team():withgiven([prepare_injector(),database_repo_is_ready(),database_is_clean(),prepare_api_server(),there_is_organization(),create_test_client(),person_is_present(),there_is_team("Test Team 1"),auth_is_ready(),])ascontext:client:TestClient=context.clientorganization_id:ulid.ULID=context.organization_idteam_repo:TeamRepository=context.injector.get(TeamRepository)withwhen():payload={"command_name":"AddPersonToTeamCommand","entity_type":"team","payload":{"team_id":str(context.team_id),"person_id":str(context.person_id),}}response=client.post(f'/api/v1/organizations/{organization_id}/teams/{context.team_id}',headers=context.add_token(),json=payload)withthen():team=team_repo.find_one(context.team_id)assert_that(response.status_code,equal_to(200))assert_that(team.people,has_item(context.person_id))deftest_a_list_of_teams_for_the_current_organization_should_be_retrievable():withgiven([prepare_injector(),database_repo_is_ready(),database_is_clean(),prepare_api_server(),there_is_organization(),create_test_client(),person_is_present(),there_is_team(name="Test Team 1"),there_is_team("Test Team 1"),auth_is_ready(),])ascontext:client:TestClient=context.clientorganization_id:ulid.ULID=context.organization_idwithwhen():response=client.get(f'/api/v1/organizations/{organization_id}/teams',headers=context.add_token(),)withthen():assert_that(response.json(),has_length(2))ContributingJust create a PR or something. I'll review it and merge it if it's good.