Instructure Tech Blog

Torpedoes of nerdy truth from the engineering team at Instructure

Swift: Just Follow the Types

| Comments

As Mac and iOS craftsmen we’ve been given a new tool. In some ways it looks a lot like the old tool, a tool we’ve been using for many years now. In many ways it is very different. This tool is, of course, the Swift programming language.

A strict type system is one thing that differentiates Swift from Objective-C.

Breaking the Rules: Accessible Dialog Components

| Comments

Turns out, role="dialog" isn’t your friend.

Cursor Modes

When you first start building accessible websites, you learn quickly that there are different cursor modes when using Windows screen readers, Léonie Watson explains them well here.

Certain element roles, like application and dialog will change the mode of the cursor. Very often this is not what you want. Yes, It does allow the developer to implement convenient keyboard events for the component, but it disables the normal keyboard navigation shortcuts for screen reader users. For sighted users, that would be a lot like opening your page up in Internet Explorer 5.5 on a mac.

Balanced Product Management

| Comments

If you look at job descriptions and blogs about product-y things, there are lots of opinions about what makes a great product manager. They talk about owning strategy, roadmaps, markets, and plans. You’re like the CEO of your product and use your über creativity to find the special sauce and make all the decisions. Then everyone will be on board with your vision, singing your praises, and sparkly rainbow unicorns will lead your company down the path to IPO.

However, all of that Being in Charge may actually be counterproductive to the mindset that will make you most successful—Not Being in Charge. The truth is, everyone else’s input is far more important than mine.

Approaching Accessibility Testing

| Comments

When I first started learning about accessibility, I had no idea what I was doing. I am a sighted person, and didn’t know if what I was doing was correct. I fed a URL to an online accessibility evaluator, which then told me what elements were missing on the page (ie: an image did not have an alt tag). It wasn’t until I met a blind person that I started to understand how people with visual impairments actually use the web. Over the years, I picked up a lot of insight on how to conduct accessibility testing, which I want to share with you.

Too Big to Test: Combating Test Apathy in Legacy Code

| Comments

Writing tests for large Rails apps with lots of dependencies and complicated modeling is, without question, a complete nightmare. We often spend more time wrestling with tests than we do writing code. The end result of writing tests for legacy code is unfortunately predictable: a test suite full of holes, poor coverage, and tests that aren’t actually testing the thing you think they are. Bugs begin to pile up, technical debt is avoided like the plague, and quick-fix bandaids are applied instead of addressing the problems head on.

We are then faced with a dilemma: our app has become too big and too complicated to test, and we no longer want to write tests for it because it is so painful. This is unavoidable. No matter how many conference talks we attend that promise to teach us how to writing clean, maintainable code, we’re still drowning in a bog of bad. The reality isn’t that we’re bad developers, it’s that we don’t dictate our workload, deadlines, or priorities. We have to make sacrifices in our code, which isn’t a bad thing until it is. So how do we fix it? How do we take away the pain?

The short answer: it’s not easy to fix, and it takes time.

ImageSweep : Drawable Management for Android

| Comments

Software engineering is full of trade-offs: speed/memory usage, features/bugs, etc. The list goes on and on. The Android team here at Instructure found an interesting trade-off: developer-time versus application size. As we get new icons/images from our UI/UX team, we have two choices: bundle all of them into the application or add them as they’re needed in our project. The trade-off becomes relatively straight-forward: either we spend time constantly adding images to our project or the user has to deal with their size when they install our application.

At a high-level, the solution is simple: find all the unused drawables in the project and remove them when you build for release. Historically that’s been a tedious and error-prone process, but not anymore. I’m proud to announce a new open-source script from Instructure: ImageSweep. It will run through every file in your project and check for references to drawable resources using regular expressions to check for instances of R.drawable. and @drawable/. The script will then iterate through the resource folder and delete ALL unused drawable resources.

It’s extremely easy to use. Simply run:

    python project_src_directory

where project_src_directory is the relative or absolute file-path where your source code lives. Make sure the chosen directory contains all of your source code and AndroidManifest.xml, but none of the libraries you’ve included. The script auto-determines where the project’s resource folder is and libraries can potentially break this detection.

We recently added this script to our release process for Canvas for Android. In that project, we were able to delete 2,593 files for a total of 72.37 Mbs freed on disk. This correlated to a 46% size decrease on the apk itself and 26% size decrease on the installed application.

To get started, visit the project homepage. Take note of the warnings in the README prior to using the script.

Continuous Integration

| Comments

Parallelization, Selenium, AWS, and a CI server are common implementations for agile shops, and we are no exception. Since I’ve been here, maintenance hasn’t been a nightmare, nor has it been a dream. We’ve learned a few things to streamline our maintenance process and would love to share the things that made our lives easier.

When looking at what was eating up our time, we found the differences between our CI environment and average developer’s environment was at the forefront. Most of us at Instructure use Macs, a few of us Windows, and there are a handful Linux users. Among us, browser choice varies, but the most popular is Chrome. Engineers develop locally using their own OS, browser type/version and the Ruby Selenium driver to power tests. Listed below are a few of the differences we found:

  1. AWS images were Ubuntu
  2. Variance in browser versions
  3. Selenium grid uses Java stand alone server VS local specs running using native Ruby driver
  4. Variance in native event capabilities VS Jenkins running exclusively using native events
  5. Parallelization in CI vs single threaded specs in developer’s environment

Ember Run Loop and TDD

| Comments

Each month, nerds unite at the Instructure building to share their knowledge on Ember. This month we had two presentations by a couple of Instructure engineers. Here are the videos and accompanying slides/code.

Ember Run Loop

Jason Madsen (@jason_madsen) discussed the what, why, and how of the Ember Run Loop. Learn how Ember manages the run loop for you, and cases where you will want to manage the run loop. Here’s a hint: speed and testing.


Testing Your Ember Application using TDD

Eric Berry (@cavneb) presented on how to “Test Drive” your Ember applications. Eric starts from scratch and walks through different types of tests that can be written. By the end, you will have a much better understanding of how to test your Ember application.

Slides | Code

Nerd with us!

Feel free to join our monthly meetups (even remotely). The meetings are posted at

Faster I18n Backend for Ruby Written in C

| Comments

Every so often, we like to do a hack(fest|stravaganza|nado) here at Instructure. It’s an opportunity for engineers to spend several days building something cool to improve Canvas.

For our inaugural hackthing back in May, I worked on the problem of having lots of objects in memory in Ruby 1.9. Ruby uses a mark-and-sweep garbage collector, so the more Ruby objects you have in memory, the longer each GC run will take. This can be a significant contributor to slow page loads in a large Rails app like Canvas.