Describe how you would design a QA automation framework, including patterns you would use.
For the coding portion, implement the framework's test-planning component. Given test definitions and their dependencies, return deterministic execution batches where every dependency runs before its dependent test. Return an empty list if the dependencies contain a cycle.
Input: tests is a list of dictionaries with name and optional depends_on fields. Output: a list of batches, where each batch is a list of test names.
def build_test_plan(tests):