Tools & Testing
    18 min read

    CSMS Testing Guide

    A comprehensive guide to testing your Charging Station Management System with simulated charge points.

    The Charging Station Management System (CSMS) is the brain of any electric vehicle charging network. It handles everything from user authorization and payments to load balancing and hardware monitoring.

    However, testing a CSMS is notoriously difficult. Relying on a few physical chargers in the office is not enough. Inadequate testing can lead to disastrous consequences in production, from stranded drivers unable to charge to massive revenue leaks. To build a resilient network, you need a comprehensive testing strategy that goes beyond the "happy path" and rigorously validates how your backend handles thousands of connected devices, flaky networks, and protocol edge cases.

    What is a CSMS?

    A CSMS (Charging Station Management System) is the software platform that manages a network of EV chargers. It connects to the chargers via the internet using the OCPP protocol defined by the Open Charge Alliance.

    Its core responsibilities include:

    • Connectivity: Maintaining WebSocket connections with thousands of chargers.
    • Authorization: Verifying RFID tags or app identifiers to allow charging.
    • Billing: Calculating costs based on energy usage (kWh) and time.
    • Remote Control: Resetting chargers, unlocking connectors, or updating firmware remotely.
    • Smart Charging: Balancing the available power grid capacity among multiple chargers to prevent outages.

    Why CSMS Testing is Critical

    In many software domains, a bug might mean a button doesn't work. In EV charging, a bug means a physical device fails to deliver energy, potentially leaving a user stranded.

    • Revenue Loss: If your system fails to record a StopTransaction message correctly, you might not bill the customer, losing money directly.
    • Customer Frustration: Drivers have zero tolerance for "app errors" when they are low on battery.
    • Scalability Failures: A system that works fine with 5 chargers might crash completely when 500 chargers try to reconnect simultaneously after a server restart.

    ⚠️ Risk of Bricking Hardware

    A single failed Firmware Update command pushed to 1000 chargers could potentially "brick" your entire network, requiring expensive on-site visits to fix. Automated testing of firmware flows is non-negotiable.

    Types of CSMS Tests

    1. Unit Tests

    These test individual functions. For example, testing the logic that validates an IdTag or calculates a tariff. These are fast and should cover your business logic.

    2. Integration Tests

    These verify that your CSMS services talk correctly to your database, billing provider (e.g., Stripe), and other internal microservices.

    3. OCPP Protocol Tests

    This is where tools like Mockpoint shine. You simulate a full conversation between a charger and your server to verify that your server responds correctly to OCPP messages like BootNotification or Heartbeat.

    4. Load and Stress Tests

    Simulating 1,000+ concurrent WebSocket connections to see if your server runs out of memory or file descriptors.

    5. Chaos Testing

    Intentionally injecting faults: dropping connections, sending garbage data, or simulating high network latency to ensure your system recovers gracefully.

    Essential OCPP Message Coverage

    At a minimum, your automated test suite should cover these messages:

    MessageDirectionPriorityTest Scenarios
    BootNotificationCP→CSMSCriticalAccept, Reject, Pending
    AuthorizeCP→CSMSCriticalValid, Invalid, Expired
    StartTransactionCP→CSMSCriticalSuccess, Concurrent, Offline
    StopTransactionCP→CSMSCriticalNormal, Abrupt, Timeout
    MeterValuesCP→CSMSHighPeriodic, Transactional
    StatusNotificationCP→CSMSHighAll status types
    RemoteStartCSMS→CPCriticalSuccess, Rejected
    RemoteStopCSMS→CPCriticalSuccess, Unknown

    Common Testing Scenarios

    1. Happy Path - Complete Charging Session

    The most basic test ensures a user can plugin, authorize, charge, and unplug.

    scenario:
      - boot_notification:
          expect_status: Accepted
      - status_notification:
          connector: 1
          status: Available
      - authorize:
          id_tag: "VALID123"
          expect_status: Accepted
      - start_transaction:
          connector: 1
          id_tag: "VALID123"
      - meter_values:
          energy: [0, 5000, 10000]
      - stop_transaction:
          reason: Local

    2. Offline Transaction Handling

    Chargers often lose internet connection. A robust test simulates a charger starting a transaction while offline and sending the StartTransaction message later when it reconnects. Your CSMS must handle these "late" messages correctly and not reject them because the timestamp is old.

    3. Concurrent Transactions

    What happens if Connector 1 and Connector 2 on the same station start charging at the exact same microsecond? Race conditions in database locks are common here.

    Testing Error Conditions

    Resilience comes from testing how things break.

    Network Failures

    Simulate a WebSocket disconnect right after sending StartTransaction but before receiving the confirmation. Does the charger retry? Does the server create a duplicate transaction if it receives it twice?

    Invalid Messages

    Send malformed JSON or messages with missing mandatory fields.

    Important: Input Validation

    Your CSMS should never crash on invalid input. It should log the error and close the connection gracefully. Test this by intentionally sending bad data.

    Building a Test Suite with Mockpoint

    Organize your tests logically. We recommend a directory structure like this:

    tests/
    ├── scenarios/
    │   ├── happy_path/
    │   ├── error_handling/
    │   └── edge_cases/
    ├── config/
    └── run_tests.sh

    You can then run your entire suite with a simple loop in your CI/CD pipeline:

    for scenario in tests/scenarios/**/*.yaml; do
      mockpoint run "$scenario" --csms ws://localhost:9000
    done

    Best Practices

    1. Scenario Naming: Use descriptive names like authorize_expired_tag.yaml so failures are easy to identify.
    2. Version Control: Keep your test scenarios in the same Git repo as your code.
    3. Continuous Testing: Run OCPP integration tests on every Pull Request.
    4. Coverage Tracking: Periodically review which message types and status codes you are covering.

    Conclusion

    Testing a CSMS is a marathon, not a sprint. Start with the critical "happy paths" that directly affect revenue, and gradually expand your suite to cover edge cases and chaos scenarios.

    Using a deterministic simulator like Mockpoint ensures that when a test fails, it's because of a real bug, not because of test flakiness.Get started with Mockpoint today to build a bulletproof charging network.