When code is poorly understood and its tests or documentation cannot be trusted, first record what it actually does for selected inputs. Check that your tests would fail if that behavior changed, then make one small, scoped edit and review what moved. Characterization tests preserve observed behavior—including bugs—so they are not proof that the behavior is correct.
What characterization tests establish
A characterization test captures an observable result of existing code: an output, side effect, or error for a particular input. It is useful when changing unfamiliar or risky code because it gives you a baseline before you edit. The point is not to endorse every behavior you find; it is to make that behavior visible so an unintended change is easier to catch.
Dakota Huang’s article, “Characterization Tests First, Then the Smallest Safe Change”, illustrates the approach with Python billing code. Its examples are one author’s demonstration, not a standardized recipe or evidence of a measured success rate. The process below keeps the useful distinction at its center: preserve behavior during refactoring, but change behavior deliberately when the task calls for a fix.
Turn the request into an observable behavior
Start by rewriting a vague ticket as a question a test can answer. Instead of “clean up billing,” specify what a selected input should produce, or which exception should occur and when. That gives the first test a narrow target and helps prevent an ostensibly small edit from becoming an unbounded redesign.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
Choose observations that matter to callers: returned values, errors, relevant side effects, and output shape. A test need not describe internal structure if the structure is not part of the behavior you need to protect.
Control inputs before capturing output
Work out which inputs can vary between runs and make them repeatable where practical. Huang’s Python example identifies the system date and a PLAN environment variable; it patches dependencies at the names used by the code under test. In Python, the correct patch target depends on how the dependency was imported, so this is an example-specific technique rather than a universal mocking rule.
- Control time when date-dependent behavior matters.
- Set environment variables explicitly instead of inheriting whatever happens to be in the test process.
- Replace network calls with controlled responses when the behavior under test does not require a live service.
- Fix random seeds or provide deterministic alternatives when random choices affect the result.
- Consider thread interleaving: if concurrency makes the observation unstable and cannot be controlled, narrow the test or defer the change.
If an important input cannot be reproduced, do not present a flaky observation as a reliable baseline. Reduce the scope to behavior you can execute and observe dependably.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Capture representative results, then inspect them
Run the selected cases and record their actual outputs. A saved snapshot or “golden” file can make a large result easier to compare, but it is only a record of what happened in that run. Huang puts the caveat plainly: “A snapshot is not a truth claim.” Review the captured values before accepting them as expectations; an unnoticed defect can be frozen just as easily as legitimate behavior.
Use a few representative cases tied to real inputs and branches rather than snapshotting everything indiscriminately. Exact equality can also be too brittle for values such as floating-point results; choose a comparison that matches the behavior the task needs to preserve.
Pin important errors and branches separately
A broad output snapshot may not make a critical error path obvious. Add direct assertions for important branches, based on the code and its callers. Huang’s example checks an unknown-plan error, including a case where input rows are empty but the plan lookup still happens. That case is useful only if the same control flow matters in your own code; do not copy it as a universal edge case.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
For each behavior you decide to protect, make the assertion state the relevant outcome clearly. That makes intentional changes easier to distinguish from regressions and reduces the chance that a large snapshot diff hides a meaningful error change.
Check that the tests can detect a change
A passing test suite is not automatically a useful safety net. Try a deliberate, temporary mutation in a copy or otherwise isolated version of the code—for example, make a clamp for negative days behave incorrectly—and confirm that the relevant test fails. Restore the code after the check.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallThis is a practical check of whether the harness notices at least that change; it does not prove complete coverage or guarantee that all important regressions will be caught. If the suite still passes, strengthen or correct the assertions before relying on it to guard the edit.
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
Make the smallest change that serves the task
With a baseline you trust, change only what the task requires and rerun the relevant tests. A local rename or helper extraction may preserve behavior; a bug fix intentionally changes it. Huang’s example replaces a strict dictionary lookup with a fallback, which changes the observable result for an unknown plan, so the old error expectation must be replaced by an expectation for the intended new behavior.
Keep the unaffected observations in place. For a behavior-preserving refactor, selected inputs should still produce the same relevant outputs and errors. For an intentional behavior change, identify which expectation should move, update it to express the desired outcome, and retain tests for unrelated behavior.
Martin Fowler’s description of the second edition of Refactoring: Improving the Design of Existing Code (2018) emphasizes controlled, small steps: “By doing them in small steps you reduce the risk of introducing errors.” That principle applies to behavior-preserving refactoring. A bug fix is different: it changes behavior by design and needs an explicit expectation for the new result.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
When to stop or narrow the work
Characterization-first work is most valuable when behavior is unclear and a change could have unintended effects. It is not a ritual required for every edit. If the relevant code is already well specified and covered by trustworthy tests, a separate baseline exercise may add little. If unstable external inputs or concurrency prevent repeatable observations, reduce the scope to what can be characterized rather than claiming comprehensive protection.
The technique also cannot decide whether an observed behavior is correct. Use the task’s requirements or an explicit product decision to determine the intended outcome; then write or revise an assertion for that intent. Keep the characterization tests that protect behavior outside the deliberate change.
Further reading
For broader strategies on changing unfamiliar code, see Michael Feathers’s Working Effectively with Legacy Code. O’Reilly lists the book as published in September 2004 by Pearson, with ISBN 0131177052, and describes it as covering common legacy-code problems and tests that help ensure changes are not made unintentionally. It is relevant background reading, not the source of Huang’s specific workflow.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools

