Generating Test Addresses from the Command Line with cURL and Bash
Introduction
Imagine a developer preparing to launch an online store. The checkout page looks ready, the payment workflow has passed its first tests, and the database is working as expected. Then the team discovers that the address form has only been tested with two sample records. It might fail when a customer enters an apartment number, a long street name, or an incomplete ZIP code.
Creating test addresses manually can quickly become repetitive. A better approach is to use command-line tools to generate, process, and save test data. With cURL and Bash, developers can build a simple workflow that creates fictional US address records, sends requests to APIs, and prepares data for automated software testing.
cURL transfers data to and from servers, while Bash runs commands and combines them into scripts. Together, they offer a practical way to automate address-related testing without building a full application first. Microsoft’s developer documentation also describes cURL as a command-line tool for making HTTP requests and interacting with REST APIs. <Cite refs={[“turn926784search10″,”turn926784search2”]}/>
This guide walks through a practical workflow, from generating fictional address records to saving them in a file and testing an API. The examples are intended for development and quality assurance. Generated records should not be treated as real or deliverable addresses.
Understanding Test Address Generation
A US mailing address commonly contains a street number, street name, optional apartment or unit number, city, state abbreviation, and ZIP code. Software that accepts these fields needs to handle both ordinary and unusual inputs.
For example, a checkout form should not break simply because an apartment number is present. A database should also store city and state information consistently, even when users enter extra spaces or different capitalization.
A command-line test address generator creates sample records that developers can use to examine these behaviours. It can produce one record for a quick manual check or many records for automated tests.
It is important to separate synthetic address generation from address verification. A generator creates sample information. A verification service checks address details against an appropriate reference system. A record that looks realistic is not necessarily a real location.
Preparing Your Command-Line Environment
Before writing a script, check that Bash and cURL are installed. On Linux and macOS, Bash is commonly available, while cURL is widely supported across operating systems. On Windows, cURL is included in current Windows versions, although Windows PowerShell 5.1 has an alias named curl that can behave differently. In that environment, use curl.exe to invoke the actual cURL program. <Cite refs={[“turn926784search10″,”turn926784search8”]}/>
Open a terminal and run:
bash --version
curl --version
These commands display the installed versions. If a command is unavailable, install it using the instructions for your operating system.
Create a working directory for the project:
mkdir address-test-project
cd address-test-project
Keeping the scripts and generated files in one directory makes the workflow easier to maintain. You can also add the directory to a version-controlled project so that other developers can reproduce the same tests.
Creating a Simple Address Generator with Bash
The first version does not need an external API. Bash can select values from predefined collections and combine them into fictional test records.
Create a file named generate_addresses.sh and add the following script:
#!/usr/bin/env bash
set -euo pipefail
streets=(
"Example Creek Drive"
"Sample Meadow Lane"
"Fictional Oak Street"
"Demo Valley Road"
"Test Garden Avenue"
)
cities=("Sampletown" "Demo City" "Exampleville")
states=("TX" "CA" "FL")
test_codes=("TEST-TX-001" "TEST-CA-001" "TEST-FL-001")
count="${1:-5}"
if ! [[ "$count" =~ ^[1-9][0-9]*$ ]]; then
echo "Please provide a positive integer." >&2
exit 1
fi
if (( count > 1000 )); then
echo "Maximum allowed count is 1000." >&2
exit 1
fi
for ((i = 0; i < count; i++)); do
street_number=$((100 + RANDOM % 9900))
street_index=$((RANDOM % ${#streets[@]}))
location_index=$((RANDOM % ${#cities[@]}))
printf '%s %s\n' \
"$street_number" "${streets[$street_index]}"
printf '%s, %s %s\n\n' \
"${cities[$location_index]}" \
"${states[$location_index]}" \
"${test_codes[$location_index]}"
done
This script uses arrays to store fictional street names and sample locations. It then selects a street and a corresponding city and state, before printing each record in a readable format.
The identifiers such as TEST-TX-001 are deliberately labelled test values, not genuine ZIP codes. This avoids suggesting that randomly assembled street details are valid mailing destinations.
Save the file and make it executable:
chmod +x generate_addresses.sh
Run the generator:
./generate_addresses.sh 10
The script generates ten records. If you leave out the number, it creates five by default. Input validation prevents accidental negative values, invalid text, and unnecessarily large requests.
Using cURL to Work with an Address API
Bash can generate local test data, while cURL can send requests to an API. This becomes useful when testing a service that accepts address information or returns structured results.
For a safe first exercise, send a request to a test endpoint that you control. For example, if your development server exposes an endpoint at http://localhost:8080/test-addresses, you can use:
curl --fail --silent --show-error \
"http://localhost:8080/test-addresses"
The command asks the local service for a response. The options make cURL report HTTP failures and show useful error messages without unnecessary output.
The URL above is an example endpoint, not a public service. You must have a compatible local server running before the request will work.
For a service that accepts JSON, you can create a test payload:
cat > sample_address.json <<'JSON'
{
"street": "123 Example Creek Drive",
"city": "Sampletown",
"state": "TX",
"zipCode": "TEST-TX-001"
}
JSON
Then send it to your own test endpoint:
curl --fail --silent --show-error \
-X POST \
-H "Content-Type: application/json" \
--data @sample_address.json \
"http://localhost:8080/test-addresses"
The server must be configured to accept that request and understand the JSON structure. A failed request may indicate that the server is unavailable, the endpoint is incorrect, or the payload does not match the API contract.
Saving Generated Addresses to a File
When testing a larger application, printing addresses directly to the terminal is not always convenient. Saving them to a file allows developers to reuse the data across multiple test runs.
You can redirect the output of the Bash script into a text file:
./generate_addresses.sh 25 > test_addresses.txt
This command generates 25 sample records and saves the output in test_addresses.txt. If you need to keep a record of previous runs, use a different filename for each test session or append new results carefully.
For automated testing, CSV is often more convenient than plain text because each address field can occupy a separate column. A CSV file might contain the headers street,city,state,test_code. You can then import the data into a spreadsheet or a test database.
When writing CSV from Bash, remember that fields containing commas or quotation marks need appropriate escaping. For more complex datasets, a dedicated CSV library or a small Python program may be more reliable than manual string formatting.
Combining Bash and cURL in One Workflow
The real benefit appears when address generation and API testing work together. Imagine a development team that needs to submit several fictional address records to its own testing endpoint. Bash can generate each record, while cURL sends the request.
A useful workflow separates three tasks:
- Generate fictional address data.
- Format each record as JSON.
- Submit it to a test endpoint and record the result.
For reliable automation, generate JSON with a tool designed to handle JSON encoding rather than building complicated JSON strings through shell concatenation. The jq command-line utility is one option when it is installed.
For example, a developer can create a JSON object and send it to a local endpoint:
jq -n \
--arg street "123 Example Creek Drive" \
--arg city "Sampletown" \
--arg state "TX" \
--arg zip "TEST-TX-001" \
'{
street: $street,
city: $city,
state: $state,
zipCode: $zip
}' > address.json
curl --fail --silent --show-error \
-H "Content-Type: application/json" \
--data @address.json \
"http://localhost:8080/test-addresses"
The example uses fixed fictional values to demonstrate safe JSON construction. You can adapt the workflow to your generator once its output format is defined.
For batch testing, add a loop that processes one record at a time and captures each response. Keep the number of requests modest until you understand the endpoint’s limits, and avoid sending synthetic records to live services without authorization.
Testing Address Validation and Error Handling
A useful test suite should do more than confirm that an API accepts an ordinary record. It should also explore how the application handles incomplete, malformed, and unexpected input.
For example, test a record with no street name, a missing state abbreviation, an empty city field, or a ZIP code containing letters. These are valuable negative test cases because they reveal whether the application returns understandable errors.
You should also test records with optional apartment numbers, longer street names, and leading or trailing spaces. The goal is to ensure that the software handles the data consistently rather than assuming every user will enter a perfect address.
For genuine postal address verification, the United States Postal Service provides an official API platform. Its Addresses API can standardize and correct US address information, including city, state, and ZIP code details. Access requires appropriate registration and credentials. <Cite refs={[“turn926784search4″,”turn926784search7”]}/>
The United States Postal Service is headquartered at 475 L’Enfant Plaza SW, Washington, DC 20260, USA. Its website is https://www.usps.com/, and its developer portal is https://developers.usps.com/.
A postal verification service should not be treated as a random address generator. Use it only when your project has a legitimate need to verify addresses and your planned use complies with the provider’s terms.
Improving Security and Reliability
Command-line automation is powerful, but a few precautions will make the workflow more dependable.
First, keep API credentials out of scripts that may be committed to a public repository. Store secrets in an appropriate environment or secret-management system, and avoid printing credentials in terminal logs.
Second, use HTTPS when connecting to external services. Avoid disabling certificate verification to make a failing request work, since doing so weakens the security of the connection.
Third, check exit codes and HTTP responses. The --fail option helps cURL report unsuccessful HTTP responses, while --show-error displays error details. For more detailed debugging, --verbose can show request and connection information, but be careful not to expose sensitive headers or tokens in shared logs.
Finally, keep generated test records clearly labelled and separate from production customer data. A fictional record should not accidentally be used for a real delivery or identity check.
Common Mistakes When Using cURL and Bash
One common mistake is assuming that a successful cURL request means the submitted address is valid. A successful HTTP response only indicates that the server returned a response within the expected protocol behaviour. The application may still have rejected the address or returned a validation error inside the response body.
Another mistake is failing to quote variables. In Bash, unquoted values may undergo word splitting and filename expansion. Quoting variables such as "$count" and "${cities[$location_index]}" helps avoid unexpected behaviour.
Developers should also avoid mixing unrelated city and state values. Keeping them together in a single structured location record reduces the risk of inconsistent output.
For shell scripting guidance, the GNU Bash Reference Manual is available at https://www.gnu.org/software/bash/manual/. For cURL options and transfer behaviour, consult the cURL documentation at https://curl.se/docs/.
Conclusion
Generating test addresses from the command line with cURL and Bash is a practical way to simplify software testing. Bash can create repeatable fictional records, while cURL can submit requests to APIs and help developers inspect responses. Together, these tools support workflows for testing address forms, validating API behaviour, and preparing data for development databases.
Start with a small local generator, save its output to a file, and then connect it to an endpoint you control. Add input validation, sensible request limits, and clear error handling as the project grows.
Most importantly, keep synthetic test data separate from verified postal information. A record created for testing is not automatically a real address. With careful scripting and responsible data handling, cURL and Bash can make address testing faster, more consistent, and easier to automate.
