Testing - ALawliet/backend GitHub Wiki

people seem to recommend

  • unit test what you can, business logic, that things get called, you can mock AWS events and services
  • to hit lambdas locally, use SAM local or Serverless Offline. SAM local seems more popular, it can also generate event templates
  • run AWS locally
    • can use LocalStack to test infra as code and cli tools, or as a more realistic mock with mini AWS services running locally
    • if just SQS/SNS, can use goaws
    • if just ddb, can use ddb local
  • then use infra as code to deploy to an AWS test environment and integration test there with real resources

https://madhead.github.io/aws-junit5/asciidoc/#_bonus_ci_with_github

https://aws.amazon.com/blogs/opensource/testing-aws-lambda-functions-written-in-java/

https://docs.aws.amazon.com/lambda/latest/dg/testing-guide.html

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-automated-tests.html

https://openupthecloud.com/how-to-test-aws-lambda/

https://medium.com/assertqualityassurance/aws-lambda-integration-test-easier-than-you-might-think-a66a9d600916

https://aws.amazon.com/blogs/devops/unit-testing-aws-lambda-with-python-and-mock-aws-services/

https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-cdk-testing.html

  • framework: JUnit5
  • mocks
    • Java -> Mockito
    • Kotlin -> Mockk
  • assertions: AssertJ, Hamcrest, Kotest
  • AWS: aws-lambda-java-tests, aws-junit5
  • test coverage report: Jacoco
  • test against real database and mock AWS: Testcontainers, Localstack

what to test:

  • mock trigger
  • that lambda handler is called with an input
  • that business logic is called
  • validate business logic output
  • input/output should use data class and @ParameterizedTest

things to mock:

  • data access, databases
  • external services we didn't write
  • stuff on the cloud
  • AWS services/events like SQS, S3
  • event json templates

things that can be tested locally:

  • isolated business logic
  • that things get called

things that may pass locally but fail on the cloud:

  • cloud config
  • service limitations

kotlin

https://www.youtube.com/watch?v=fLVUlJ-i_Qs&ab_channel=thenewboston

  • Fast
  • Isolated
  • Repeatable
  • Self-validating
  • Timely

https://www.youtube.com/watch?v=RX_g65J14H0&ab_channel=JetBrains, https://phauer.com/2018/best-practices-unit-testing-kotlin/

  • JUnit5
    • @TestInstance(PER_CLASS)
  • Naming (Backticks), Grouping (Nested)
  • Libraries
    • Mockk
    • AssertJ
  • Mock Handling
    • Don't recreate; reset!
  • Data Classes FTW
    • Equals Assertions
    • Creation Helper
    • @ParameterizedTest

https://www.youtube.com/watch?v=s6idLikuovc&ab_channel=BrandanJones

  • it's too complicated -> it's your code, not the test!
  • it interacts with external data -> used Mocked objects, create an object and tell it how to behave when used in the test
  • it calls something outside (a REST endpoint, external service, or something we don't control) -> use verify
    • verify something was called, with a certain set of parameters, x amount of times

lambdas

https://www.youtube.com/watch?v=Mu0mWa6th4c&ab_channel=JamesEastham

  • unit test locally, test everything else in the cloud with actual cloud resources for more complicated stuff
  • unit test should have no external dependencies, mock those
    • data access
  • @ParameterizedTest, @Event for APIGatewayProxyRequest
  • can use mocks to simulate throwing exceptions
  • can use debugger on code while test runs to step through business logic locally
  • SAM local sam build runs the unit tests
ArgumentCaptor<Product> productArgumentCaptor = ArgumentCaptor.forClass(Product.class);
Mockito.verify(testDataAccessClient).StoreProduct(productArgumentCaptor.capture());

https://www.youtube.com/watch?v=RienImDKxlo&ab_channel=DiegoPacheco

  • aws-lambda-java-tests
    • allows simulating different triggers using event.json files: SQS, S3, Cloudwatch
    • make an event where you have the message in detail, another one where you're missing the message, etc.
    • ScheduledEvent event = eventLoader.loadScheduledEvent("event.json")
@ParameterizedTest
@Event(value = "event.json", type = ScheduledEvent.class)
public void testLoadEventBridgeEvent(ScheduledEvent event) {}

SAM

  • requires Docker
  • uses CloudFormation, so it looks similar to their templates
  • creates an S3 bucket to store artifacts

https://www.youtube.com/watch?v=AUQRyl1SNcU&ab_channel=BeABetterDev

  • just AWS::Serverless construct
  • template.yaml with different setups for regular lambda function, from APIGW, SNS, etc.
sam local invoke -e ./lambda/lambda_event.json LambdaDemoFunction

https://www.youtube.com/watch?v=ku80wC3QqwQ&ab_channel=BeABetterDev

  • with CDK, which spits out CF, so it's a matter of if you want to write a SAM yaml template or CDK in your language
sam local invoke -t ./cdk.out/CdkLambdaLocalStack.template.json
sam local generate-event sns notification
sam local invoke -t ./cdk.out/CdkLambdaLocalStack.template.json -e ./events/sns_event.json

https://www.youtube.com/watch?v=fEZE3rm8Ma8&ab_channel=TravisMedia

Mockito

https://www.youtube.com/watch?v=HsQ9OwKA79s&t=908s&pp=ygUHbW9ja2l0bw%3D%3D

https://www.youtube.com/watch?v=MztH6vkeFVk&t=167s&ab_channel=AneeshMistry

https://www.youtube.com/watch?v=aNCPy803rkI&t=576s&ab_channel=CodingSimplified

aws-lambda-java-tests

https://aws.amazon.com/blogs/opensource/testing-aws-lambda-functions-written-in-java/

LocalStack

https://www.youtube.com/watch?v=ATo19E6oegE&ab_channel=DevOpsJourney

https://www.youtube.com/watch?v=SYCeM-Q6nRs&t=2s&pp=ygUObG9jYWxzdGFjayBjZGs%3D

TestContainers

is more of a standard for using containers in JUnit, so should probably use this instead of localstack-utils

https://www.freecodecamp.org/news/integration-testing-using-junit-5-testcontainers-with-springboot-example/

IaC

https://www.youtube.com/watch?v=3_sqr0G9zb0&t=260s&pp=ygUObG9jYWxzdGFjayBjZGs%3D

  • can use SAM local/CDK to deploy to LocalStack to test IaC locally instead of cloud

https://www.youtube.com/watch?v=eszNbLXoaGQ&pp=ygUObG9jYWxzdGFjayBjZGs%3D

https://aws.amazon.com/blogs/compute/better-together-aws-sam-and-aws-cdk/

CF/SAM template -> AWS SAM CLI
CDK -> AWS SAM CLI
                               -> LocalStack

https://www.playingaws.com/posts/how-to-create-serverless-applications-with-cdk-and-sam/

  • CDK to build lambdas and synth to CF (instead of SAM template)
  • SAM to test invoke against them
  • spin up local DDB in Docker

https://fourco.nl/blogs/speeding-up-lambda-development/

  • SAM Accelerate avoids deploying the whole application through CF for small changes of code

https://beabetterdev.com/2022/05/06/how-to-test-your-aws-lambda-function-locally-with-cdk/#:~:text=You%20can%20use%20SAM%20and,be%20generated%20locally%20using%20SAM

⚠️ **GitHub.com Fallback** ⚠️