Skip to content

Install and use a non-GUI connection speed test tool

Yesterday on Twitter, Dave Hamilton tweeted…

What is this speedtest exactly? And what is brew, you may also be wondering? You may also be wondering why, if you have brew, Dave's command doesn't work…that's because it's actually brew install speedtest_cli…but I'm getting ahead of myself.

speedtest is a command line interface (i.e. Unix app run from Terminal) to the connection speed tests at Speedtest.net—you get the results without the fancy animated graphics. And Brew is "the missing package manager for macOS." In other words, it's an app to help you install (and uninstall) other apps.

Here's how speedtest looks in its default mode—note that I've sped things up greatly for the GIF…

Much nicer to me, though, is the simplified version:

$ speedtest_cli --simple
Ping: 9.482 ms
Download: 94.23 Mbit/s
Upload: 68.66 Mbit/s

No animated dots, just three lines with the results. As you might expect if you read here regularly, I also wrote a Keyboard Maestro macro (of course I did!) that makes it really easy to run the simple version of the test, and does some editing of the output to simplify the display:

If you'd like to install speedtest (and maybe add the macro)—even if you don't want to install Brew to do so—keep reading…

Installation

With Brew installed

If you have Brew installed, installation is as simple as brew install speedtest_cli in Terminal. Note that the installed name is simply speedtest, not speedtest_cli.

Without Brew installed

The project is hosted on Github, and there are many ways to install from there. Perhaps the easiest would be via Terminal:

$ curl -Lo speedtest https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py
$ chmod +x speedtest
$ mv speedtest path/to/where/you/want/it/to/live

Obviously, you need to edit the third line to move the app to the directory where you'd like it to live, unless your system has a very unique directory structure that matches the above!

Using speedtest

As seen above, usage is as simple as typing speedtest or speedtest --simple in Terminal. There are other options, like --secure for a secure connection; type speedtest --help for a full list.

But running from Terminal means you have to be in Terminal, and this is something that I'd like to be able to run from wherever. Enter Keyboard Maestro

The Keyboard Maestro macro version

I actually wrote this twice; once in super-simple form, and then a fancier version that does some processing to change the display of the output.

The super simple version

This is a four-step macro [download], in which three of the steps don't really do anything at all:

The first and last steps lock the macro so it can't be activated twice at the same time (important for a slow-running macro like this). The second line displays a notification, letting you know the macro is running and that the results will also appear in the notifications area of the screen. The third line just calls speedtest. Note that you'll need to provide the full path to the program; I used Brew to install, so mine is in /usr/local/bin.

In its simple form, the notification contains the three output lines from simple mode, scrunched to fit on two lines in Notification Center:

And while this is fine, I decided I wanted it to fit on one line, and I didn't need long words to describe things. And so that led to…

The fancy version

The macro itself [download] is basically the same as the simple version, except instead of calling speedtest directly, I call a script:

To use this macro, you'll need to recreate my script, and modify the macro to point to your version…unless your macOS username also happens to be robg, you store your scripts in a folder named bin in your home folder, and you named your script pysts.

The script is a Python script, the first I've ever written. And before I post the code, here's the disclaimer: I know there are myriad ways to process the speedtest output that are probably way more efficient than my solution. A script isn't required, in fact—some combination of sed and piping and whatnot will get the job done. But for me, with my level of skill, the Python script works well because it's easy to modify, and I'll understand what I did when I look at it in the future.

So here's the code...

Knowing nothing at all about Python, this (of course) took longer than expected. Things I didn't know were plentiful, including basic stuff like "Wait, you can't process strings unless you first import a string module?" But it works, and it seems pretty efficient—the waiting time is 99% speedtest testing time, not the script. The output is the one-line version seen near the top of this tip.

With this very simple script, I can run a connection speed test by either typing a simple phrase (=spd= for now), or by selecting my speed test entry in Keyboard Maestro's menu bar icon. (I didn't want to waste a hot key for something I won't run all that often.)

4 thoughts on “Install and use a non-GUI connection speed test tool”

    1. I just installed it on another Mac, and it worked with speedtest_cli, even though the app name is officially speedtest-cli. I would guess it's aliased so as to not break anyone's scripts?

      -rob.

  1. Ouch. Not working at all on my iMac with High Sierra :(

    $ speedtest

    speedtest-cli
    Retrieving speedtest.net configuration...
    Traceback (most recent call last):
    File "/usr/local/bin/speedtest-cli", line 2000, in
    main()
    File "/usr/local/bin/speedtest-cli", line 1986, in main
    shell()
    File "/usr/local/bin/speedtest-cli", line 1872, in shell
    speedtest = Speedtest(
    File "/usr/local/bin/speedtest-cli", line 1091, in init
    self.get_config()
    File "/usr/local/bin/speedtest-cli", line 1121, in get_config
    uh, e = catch_request(request, opener=self._opener)
    File "/usr/local/bin/speedtest-cli", line 730, in catch_request
    uh = _open(request)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 531, in open
    response = meth(req, response)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 640, in http_response
    response = self.parent.error(
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 563, in error
    result = self._call_chain(*args)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 755, in http_error_302
    return self.parent.open(new, timeout=req.timeout)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 525, in open
    response = self._open(req, data)
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 542, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
    File "/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/urllib/request.py", line 502, in _call_chain
    result = func(*args)
    File "/usr/local/bin/speedtest-cli", line 563, in https_open
    SpeedtestHTTPSConnection,
    NameError: name 'SpeedtestHTTPSConnection' is not defined

    $

    1. I have a High Sierra virtual machine, so I tried there: I didn't use the homebrew method, as I don't have Homebrew installed on the VM. But using the "Without homebrew installed" method, it worked, with one caveat: The first time I ran it, it threw an error:

      $ ./speedtest
      Retrieving speedtest.net configuration...
      Cannot retrieve speedtest configuration

      But then I ran it again, and it worked.

      I wish I could debug your issue, but I can't—it does look related to the error I got ... what happens if you run it again?

      -rob.

Comments are closed.