You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python新手求教:未封装函数/类的脚本能否用unittest做单元测试?

Can You Unit Test Unstructured AWS Glue Scripts?

Absolutely! You can absolutely write unit tests for Python scripts that aren’t wrapped in functions or classes—including AWS Glue scripts like the join/relationalize example you mentioned. The key is to make small, non-breaking changes to the script to enable testability, while keeping it fully compatible with AWS Glue’s requirement to run the entire script as the entry point. Here’s how to do it step by step:

1. Refactor the Script (Gently) for Testability

You don’t have to rewrite the entire script—just extract the core logic into reusable functions. This way, you can test individual pieces without running the full Glue job, while the original script still works exactly as it did before in Glue.

For example, take the original script’s top-level code:

# Original top-level code
glueContext = GlueContext(SparkContext.getOrCreate())
datasource0 = glueContext.create_dynamic_frame.from_catalog(database="db", table_name="table")
datasource1 = glueContext.create_dynamic_frame.from_catalog(database="db", table_name="another_table")
join1 = datasource0.join(keys1=["id"], keys2=["foreign_id"], frame2=datasource1)
relationalized_df = join1.relationalize("root", "s3://output/path")
glueContext.write_dynamic_frame.from_options(frame=relationalized_df, connection_type="s3", ...)

Refactor it into functions, then keep the original execution flow intact at the bottom:

def init_glue_context():
    return GlueContext(SparkContext.getOrCreate())

def load_data(glue_context, db_name, table_name):
    return glue_context.create_dynamic_frame.from_catalog(database=db_name, table_name=table_name)

def join_dynamic_frames(frame1, frame2, key1, key2):
    return frame1.join(keys1=[key1], keys2=[key2], frame2=frame2)

def relationalize_data(frame, root_name, output_path):
    return frame.relationalize(root_name, output_path)

def write_output(glue_context, frame, connection_params):
    glue_context.write_dynamic_frame.from_options(frame=frame, **connection_params)

# Keep the original execution flow for Glue
if __name__ == "__main__":
    ctx = init_glue_context()
    data0 = load_data(ctx, "db", "table")
    data1 = load_data(ctx, "db", "another_table")
    joined_data = join_dynamic_frames(data0, data1, "id", "foreign_id")
    relationalized = relationalize_data(joined_data, "root", "s3://output/path")
    write_output(ctx, relationalized, {"connection_type": "s3", ...})

This change doesn’t affect how Glue runs the script (it still executes the full flow when run as the entry point), but now you can test each function independently.

2. Mock AWS Glue Dependencies for Local Testing

Since you can’t easily spin up a real Glue context locally, use Python’s built-in unittest.mock library to simulate Glue-specific objects like GlueContext and DynamicFrame. This lets you test your logic without needing an AWS account or Glue environment.

For example, here’s a test case for the join_dynamic_frames function:

import unittest
from unittest.mock import Mock
import your_script_name  # Replace with your script's filename

class TestGlueScript(unittest.TestCase):
    def test_join_dynamic_frames(self):
        # Create mock DynamicFrames
        mock_frame1 = Mock()
        mock_frame2 = Mock()
        mock_joined_frame = Mock()
        
        # Set up the mock join method to return our mock result
        mock_frame1.join.return_value = mock_joined_frame
        
        # Call the function under test
        result = your_script_name.join_dynamic_frames(mock_frame1, mock_frame2, "id", "foreign_id")
        
        # Verify the join was called with the correct parameters
        mock_frame1.join.assert_called_once_with(keys1=["id"], keys2=["foreign_id"], frame2=mock_frame2)
        # Verify we got the expected result
        self.assertEqual(result, mock_joined_frame)

if __name__ == '__main__':
    unittest.main()

For more realistic testing, you can also use the aws-glue-libs package (available via Conda) to create a local Glue context and work with real DynamicFrame objects—this is great for testing data transformation logic that relies on Glue’s specific methods.

3. Run Your Tests Locally

Once you’ve written your test cases, run them using Python’s unittest module just like any other test suite:

python -m unittest test_your_script.py -v

Key Reassurance for Your Glue Concern

You mentioned that Glue can only run the entire script as the entry point—this approach doesn’t break that. When Glue executes your script, it runs the full flow defined in the if __name__ == "__main__": block, just like it did before. The refactored functions are just there to make testing easier; Glue doesn’t need to run them individually.

内容的提问来源于stack exchange,提问作者Michael Z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 20:27:52