Mapper.pm 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. package Test::Mapper;
  2. use strict;
  3. use warnings;
  4. #ABSTRACT: Map what parts of a codebase changing ought trigger acceptance tests
  5. =head1 DESCRIPTION
  6. The general tradition in perl unit testing is to map 'what to test' when a piece of code changes is simple:
  7. lib/Foo/Bar.pm -> t/lib-Foo-Bar.t (or t/lib-Foo/Bar.t)
  8. bin/baz -> t/bin-baz.t
  9. Unfortunately things tend to get messy when you engage in more complicated testing, such as integration testing.
  10. There, you have one-to-many relationships, but which can still be easily discerned programmatically via inspecting @INC.
  11. That is unless you require() modules (or worse, read & eval/exec), in which case analysis via PPI must be brought to bear.
  12. Still, most people solve that particular problem with the doctor's adage about "not doing things that hurt".
  13. However, acceptance tests will blow out your build server's thinking budget quickly, being a many-to-many mapping.
  14. To make things worse, much of the stack isn't necessarily in $LANGUAGE_OF_CHOICE.
  15. Furthermore this is not something that can simply be avoided via careful structuring.
  16. Knowing all this, what then shall we do? Cheat.
  17. AKA breaking an insoluble problem into many smaller soluble ones.
  18. It is well within the ability of a test author to discern the route via which an acceptance test accesses a feature.
  19. Indeed this is necessarily so.
  20. As such if we structure our mapping from this perspective life becomes quickly simplified.
  21. Taking as an example an average web application, we can imagine a mapping like:
  22. t/acceptance/DoFoobarFeature.t -> GET /ez/bez, POST /huth/buth, ...
  23. And every single so loaded "endpoint" necessarily has a number of resources loaded.
  24. It is well within the realm of possibility to hit these endpoints with L<Playwright>, grab a HttpARchive and map that to the relevant source files in the repo.
  25. Similarly one can (in most cases) do the same thing with normal applications via C<ldd>, C<strace> and so forth.
  26. =cut