@@ -1902,4 +1902,210 @@ def test_bubble_sort(input, expected_output):
19021902
19031903 # Check that comments were added
19041904 modified_source = result .generated_tests [0 ].generated_original_test_source
1905- assert modified_source == expected
1905+ assert modified_source == expected
1906+
1907+ def test_async_basic_runtime_comment_addition (self , test_config ):
1908+ """Test basic functionality of adding runtime comments to async test functions."""
1909+ os .chdir (test_config .project_root_path )
1910+ test_source = """async def test_async_bubble_sort():
1911+ codeflash_output = await async_bubble_sort([3, 1, 2])
1912+ assert codeflash_output == [1, 2, 3]
1913+ """
1914+
1915+ generated_test = GeneratedTests (
1916+ generated_original_test_source = test_source ,
1917+ instrumented_behavior_test_source = "" ,
1918+ instrumented_perf_test_source = "" ,
1919+ behavior_file_path = test_config .tests_root / "test_module__unit_test_0.py" ,
1920+ perf_file_path = test_config .tests_root / "test_perf.py" ,
1921+ )
1922+ generated_tests = GeneratedTestsList (generated_tests = [generated_test ])
1923+
1924+ original_test_results = TestResults ()
1925+ optimized_test_results = TestResults ()
1926+
1927+ original_invocation = self .create_test_invocation ("test_async_bubble_sort" , 500_000 , iteration_id = '0' ) # 500μs
1928+ optimized_invocation = self .create_test_invocation ("test_async_bubble_sort" , 300_000 , iteration_id = '0' ) # 300μs
1929+
1930+ original_test_results .add (original_invocation )
1931+ optimized_test_results .add (optimized_invocation )
1932+ original_runtimes = original_test_results .usable_runtime_data_by_test_case ()
1933+ optimized_runtimes = optimized_test_results .usable_runtime_data_by_test_case ()
1934+ result = add_runtime_comments_to_generated_tests (generated_tests , original_runtimes , optimized_runtimes )
1935+
1936+ modified_source = result .generated_tests [0 ].generated_original_test_source
1937+ assert "# 500μs -> 300μs" in modified_source
1938+ assert "codeflash_output = await async_bubble_sort([3, 1, 2]) # 500μs -> 300μs" in modified_source
1939+
1940+ def test_async_multiple_test_functions (self , test_config ):
1941+ os .chdir (test_config .project_root_path )
1942+ test_source = """async def test_async_bubble_sort():
1943+ codeflash_output = await async_quick_sort([3, 1, 2])
1944+ assert codeflash_output == [1, 2, 3]
1945+
1946+ async def test_async_quick_sort():
1947+ codeflash_output = await async_quick_sort([5, 2, 8])
1948+ assert codeflash_output == [2, 5, 8]
1949+
1950+ def helper_function():
1951+ return "not a test"
1952+ """
1953+ generated_test = GeneratedTests (
1954+ generated_original_test_source = test_source ,
1955+ instrumented_behavior_test_source = "" ,
1956+ instrumented_perf_test_source = "" ,
1957+ behavior_file_path = test_config .tests_root / "test_module__unit_test_0.py" ,
1958+ perf_file_path = test_config .tests_root / "test_perf.py"
1959+ )
1960+
1961+ generated_tests = GeneratedTestsList (generated_tests = [generated_test ])
1962+
1963+ original_test_results = TestResults ()
1964+ optimized_test_results = TestResults ()
1965+
1966+ original_test_results .add (self .create_test_invocation ("test_async_bubble_sort" , 500_000 , iteration_id = '0' ))
1967+ original_test_results .add (self .create_test_invocation ("test_async_quick_sort" , 800_000 , iteration_id = '0' ))
1968+
1969+ optimized_test_results .add (self .create_test_invocation ("test_async_bubble_sort" , 300_000 , iteration_id = '0' ))
1970+ optimized_test_results .add (self .create_test_invocation ("test_async_quick_sort" , 600_000 , iteration_id = '0' ))
1971+
1972+ original_runtimes = original_test_results .usable_runtime_data_by_test_case ()
1973+ optimized_runtimes = optimized_test_results .usable_runtime_data_by_test_case ()
1974+
1975+ result = add_runtime_comments_to_generated_tests (generated_tests , original_runtimes , optimized_runtimes )
1976+
1977+ modified_source = result .generated_tests [0 ].generated_original_test_source
1978+
1979+ assert "# 500μs -> 300μs" in modified_source
1980+ assert "# 800μs -> 600μs" in modified_source
1981+ assert (
1982+ "helper_function():" in modified_source
1983+ and "# " not in modified_source .split ("helper_function():" )[1 ].split ("\n " )[0 ]
1984+ )
1985+
1986+ def test_async_class_method (self , test_config ):
1987+ os .chdir (test_config .project_root_path )
1988+ test_source = '''class TestAsyncClass:
1989+ async def test_async_function(self):
1990+ codeflash_output = await some_async_function()
1991+ assert codeflash_output == expected
1992+ '''
1993+ generated_test = GeneratedTests (
1994+ generated_original_test_source = test_source ,
1995+ instrumented_behavior_test_source = "" ,
1996+ instrumented_perf_test_source = "" ,
1997+ behavior_file_path = test_config .tests_root / "test_module__unit_test_0.py" ,
1998+ perf_file_path = test_config .tests_root / "test_perf.py"
1999+ )
2000+
2001+ generated_tests = GeneratedTestsList (generated_tests = [generated_test ])
2002+
2003+ invocation_id = InvocationId (
2004+ test_module_path = "tests.test_module__unit_test_0" ,
2005+ test_class_name = "TestAsyncClass" ,
2006+ test_function_name = "test_async_function" ,
2007+ function_getting_tested = "some_async_function" ,
2008+ iteration_id = "0" ,
2009+ )
2010+
2011+ original_runtimes = {invocation_id : [2000000000 ]} # 2s in nanoseconds
2012+ optimized_runtimes = {invocation_id : [1000000000 ]} # 1s in nanoseconds
2013+
2014+ result = add_runtime_comments_to_generated_tests (generated_tests , original_runtimes , optimized_runtimes )
2015+
2016+ expected_source = '''class TestAsyncClass:
2017+ async def test_async_function(self):
2018+ codeflash_output = await some_async_function() # 2.00s -> 1.00s (100% faster)
2019+ assert codeflash_output == expected
2020+ '''
2021+
2022+ assert len (result .generated_tests ) == 1
2023+ assert result .generated_tests [0 ].generated_original_test_source == expected_source
2024+
2025+ def test_async_mixed_sync_and_async_functions (self , test_config ):
2026+ os .chdir (test_config .project_root_path )
2027+ test_source = """def test_sync_function():
2028+ codeflash_output = sync_function([1, 2, 3])
2029+ assert codeflash_output == [1, 2, 3]
2030+
2031+ async def test_async_function():
2032+ codeflash_output = await async_function([4, 5, 6])
2033+ assert codeflash_output == [4, 5, 6]
2034+
2035+ def test_another_sync():
2036+ result = another_sync_func()
2037+ assert result is True
2038+ """
2039+ generated_test = GeneratedTests (
2040+ generated_original_test_source = test_source ,
2041+ instrumented_behavior_test_source = "" ,
2042+ instrumented_perf_test_source = "" ,
2043+ behavior_file_path = test_config .tests_root / "test_module__unit_test_0.py" ,
2044+ perf_file_path = test_config .tests_root / "test_perf.py"
2045+ )
2046+
2047+ generated_tests = GeneratedTestsList (generated_tests = [generated_test ])
2048+
2049+ original_test_results = TestResults ()
2050+ optimized_test_results = TestResults ()
2051+
2052+ # Add test invocations for all test functions
2053+ original_test_results .add (self .create_test_invocation ("test_sync_function" , 400_000 , iteration_id = '0' ))
2054+ original_test_results .add (self .create_test_invocation ("test_async_function" , 600_000 , iteration_id = '0' ))
2055+ original_test_results .add (self .create_test_invocation ("test_another_sync" , 200_000 , iteration_id = '0' ))
2056+
2057+ optimized_test_results .add (self .create_test_invocation ("test_sync_function" , 200_000 , iteration_id = '0' ))
2058+ optimized_test_results .add (self .create_test_invocation ("test_async_function" , 300_000 , iteration_id = '0' ))
2059+ optimized_test_results .add (self .create_test_invocation ("test_another_sync" , 100_000 , iteration_id = '0' ))
2060+
2061+ original_runtimes = original_test_results .usable_runtime_data_by_test_case ()
2062+ optimized_runtimes = optimized_test_results .usable_runtime_data_by_test_case ()
2063+
2064+ result = add_runtime_comments_to_generated_tests (generated_tests , original_runtimes , optimized_runtimes )
2065+
2066+ modified_source = result .generated_tests [0 ].generated_original_test_source
2067+
2068+ assert "# 400μs -> 200μs" in modified_source
2069+ assert "# 600μs -> 300μs" in modified_source
2070+ assert "# 200μs -> 100μs" in modified_source
2071+
2072+ assert "async def test_async_function():" in modified_source
2073+ assert "await async_function([4, 5, 6])" in modified_source
2074+
2075+ def test_async_complex_await_patterns (self , test_config ):
2076+ os .chdir (test_config .project_root_path )
2077+ test_source = """async def test_complex_async():
2078+ # Multiple await calls
2079+ result1 = await async_func1()
2080+ codeflash_output = await async_func2(result1)
2081+ result3 = await async_func3(codeflash_output)
2082+ assert result3 == expected
2083+
2084+ # Await in context manager
2085+ async with async_context() as ctx:
2086+ final_result = await ctx.process()
2087+ assert final_result is not None
2088+ """
2089+ generated_test = GeneratedTests (
2090+ generated_original_test_source = test_source ,
2091+ instrumented_behavior_test_source = "" ,
2092+ instrumented_perf_test_source = "" ,
2093+ behavior_file_path = test_config .tests_root / "test_module__unit_test_0.py" ,
2094+ perf_file_path = test_config .tests_root / "test_perf.py"
2095+ )
2096+
2097+ generated_tests = GeneratedTestsList (generated_tests = [generated_test ])
2098+
2099+ original_test_results = TestResults ()
2100+ optimized_test_results = TestResults ()
2101+
2102+ original_test_results .add (self .create_test_invocation ("test_complex_async" , 750_000 , iteration_id = '1' )) # 750μs
2103+ optimized_test_results .add (self .create_test_invocation ("test_complex_async" , 450_000 , iteration_id = '1' )) # 450μs
2104+
2105+ original_runtimes = original_test_results .usable_runtime_data_by_test_case ()
2106+ optimized_runtimes = optimized_test_results .usable_runtime_data_by_test_case ()
2107+
2108+ result = add_runtime_comments_to_generated_tests (generated_tests , original_runtimes , optimized_runtimes )
2109+
2110+ modified_source = result .generated_tests [0 ].generated_original_test_source
2111+ assert "# 750μs -> 450μs" in modified_source
0 commit comments