# Read Me First: Welcome!

This instructor guide is intended to help you get started quickly with the material. (If you're reading this on GitHub, you might prefer the much nicer formatting of the [Gitbook version](https://teach.saasbook.info).)

If you're new to the course, you might want to quickly scan the Pedagogy and Teaching Tips sections first, so that you know what you're getting into!

The following materials are public and available to everyone:

* The free-to-download [textbook](http://www.saasbook.info), also available as an [interactive website](https://e.saasbook.info)
* A set of lecture videos, one per textbook section, as [YouTube playlists](https://www.youtube.com/user/saasbook/playlists)
* Lecture slides, one deck per textbook chapter, as [Google Slides](https://drive.google.com/drive/folders/1YJpubP97LxvfJYLYXsq4JxQ-TQIWZO2f?usp=sharing)
* [Practice exams](https://github.com/saasbook/courseware/tree/main/practice-exams) from previous offerings of the course at UC Berkeley
* CHIPS (Coding & Hands-on Integrated Projects)—“learn by doing” programming-related assignments. If you adopt Codio for the course, the assignments are preconfigured including auto-graders. You can also use the assignments manually outside of Codio, without the preconfigured autograders.
* A bank of non-coding questions (including some Faded Parsons problems) appropriate for summative assessments, authored using [PrairieLearn](https://prairielearn.org).

Access to the following requires you to join the [esaas-instructors](http://groups.google.com/group/esaas-instructors) Google group **(note: you  must be signed in to a Google account for the link to work)**. In your join request, please **include your GitHub username and a link to evidence that you are an instructor** (web page, etc.). Once you're a member, you can email <esaas-instructors@googlegroups.com> with questions/support.&#x20;

* Per-chapter [activity worksheets](https://github.com/saasbook/courseware/tree/main/discussions) (with instructor solutions) for flipped-classroom or small group work
* Per-chapter quizzes (see separate page in this book describing them) consisting of mostly multiple-choice questions to test understanding. You can modify and deliver the quizzes via PrairieLearn, or use legacy materials to generate the quizzes yourself.
* [Open-ended exam questions](https://github.com/saasbook/open-response-exam-questions) suitable for written exams.
* Questions for exams that have a coding component (see separate page in this book for details). You can deliver these via Codio which includes autograding, or administer them manually.

This manual guides you through using the above materials and provides pedagogical information and background as well.

## About Codio

Codio is an all-in-one Web-based IDE that also includes our textbook, autograding, and LMS integration. This is the recommended way to administer CHIPS, since students need only a web browser and everything is preconfigured including the autograders. ***Note**: We have no connection to Codio and do not receive any royalty if you use their service, but it makes the course much easier to manage, so we highly recommend using it.*

**How to get started:**

1. Create a Codio account—[you can start with a free trial](https://codio.com/esaas)
2. [Add the integrated ESaaS textbook to your Codio account](https://www.codio.com/resources/esaas) (via the giant orange button)
3. Preview the content [the quick way](https://docs.codio.com/courses/grading/#previewing-assignments), or preview it [as a test student](https://docs.codio.com/courses/classes/#test-students) to see the full student experience
4. [Contact Codio support](https://docs.codio.com/dashboard/account/#customer-technical-support) to convert your trial into a full account. You can then either [integrate with your LMS](https://docs.codio.com/courses/lti1_0/) or [add students directly to Codio](https://docs.codio.com/courses/lti1_0/).

## About PrairieLearn

As of 2021, we converted all summative assessments (quizzes/exams) and all non-CHIPS formative assessments (practice problems, practice questions not involving code-writing) to use the [PrairieLearn](https://prairielearn.org) (PL) assessment authoring system. Besides allowing us to create rich interactive exercises, PL allows randomizing elements of the questions, making them suitable for summative assessments as well as practice. Contact Armando Fox directly to get these; in the future we will use PrairieLearn "question sharing" features to share them directly in PrairieLearn itself.

PL is open source and you can download and run it yourself (not trivial), or contact the nice folks at [PrairieLearn.com](https://prairielearn.com) to host it for you. **Note:** We have no formal connection to PL so you'll need to contact them directly for support, but we believe it’s the best system we have seen for authoring rich interactive exercise for this course.


# New for Fall 2024

An executive summary of updates to the ESaaS course materials for 2024:

* Virtually all of the lecture videos have been re-recorded during Fall 2023, though there are a few gaps. We've updated the YouTube playlist in this instructor's guide (see left) with links to the new videos.&#x20;
* The Codio-based CHIPS are being updated to work with Codio's new "Guides" format (the in-IDE textbook) and are being updated to Rails 7 and Ruby 3 (thanks to Jairo Velasquez at Codio!), and the accompanying documentation in both GitHub and Codio updated. Instructors who use Codio should receive notifications of these updates from Codio so they can apply them to their individual courses. &#x20;
* We have moved virtually all of the non-coding-intensive exercises (quizzes, homeworks, exams) to PrairieLearn. [Read the details and get access to these materials](/chips/quizzes-exams-practice-problems). Some of the PrairieLearn exercises make use of [Faded Parsons Problems](https://acelab.berkeley.edu/projects/faded-parsons/), invented by UC Berkeley PhD student Nate Weinman in 2021, which provide a well-defined intermediate exercise type between code comprehension (code-reading) and code-writing. FPPs involve shorter programming tasks than the Codio CHIPS, but still exercise knowledge of programming. We'll be adding more self-check questions and novel exercises in PrairieLearn format. Note that the "Exercises for Flipped Classroom" and "Additional Materials" at left continue to be available, and we will update those repositories with more flipped-classroom worksheets as we create them. Contributions are welcome!
* There is a new CHIPS 8.5 that is *not* based on Codio but instead uses [Faded Parsons Problems to provide a "kinder, gentler" introduction to RSpec test writing](https://dl.acm.org/doi/10.1145/3502718.3524789); it's gone through two pilot cycles locally and has been very well received, so we'll be creating more like it. If you get access to the above PrairieLearn materials you'll have access to this CHIPS as well.
* You can now [download](https://saasbook.info) the newest release of the book (current version 2.0b8, which is also packaged in Codio now). A notable improvement is a list of [*competencies*](/chips/quizzes-exams-practice-problems) at the end of every book section that define specific skills students should be able to demonstrate based on the material in that chapter. Some of these competencies are linked directly to PrairieLearn exercises that test them, so if you get access to the PrairieLearn materials as above and are using PrairieLearn in the course, you could put these questions directly on quizzes or homeworks. Others are exercised in the CHIPS. The long term goal is to provide one or more PrairieLearn or CHIPS exercises for *every* competency.
* There's a new "[SaaS In the News](/chips/saas-in-the-news)" page on this site (see left)where I'm collecting one-line summaries of news articles or videos related to the course topics, organized roughly by chapter. A few of these are "evergreen" topics and others are specific incidents relevant to course content.

Any and all contributions to the materials are welcome; email me to learn more!


# Competency-Based Questions in Textbook

In the latest (2nd) edition of the [textbook](https://saasbook.info), the end of each section, in addition to featuring "Check your understanding" questions, now also identifies one or more *competencies* associated with that section—things the learner should be *able to do* to demonstrate mastery of the content in that section.

A subset of these competencies is associated with PrairieLearn auto-graded questions that instructors can include in their homework assignments or quizzes. You can preview these questions as an instructor, and decide to deploy PrairieLearn to give access to your students in the form of homework or quiz questions. [Learn more](/chips/quizzes-exams-practice-problems) about PrairieLearn and how to preview or deploy these questions.&#x20;


# Lectures, Slides, Video Interviews

**Video Lecturelets**

At Berkeley, we constructed our lectures to be broken up into 7-20 minute segments. In general, each segment corresponds to a textbook section, with a few exceptions and some supplementary topics; some segments were later added or updated with studio-recorded lectures. Instructors have used these lectures to prepare/inspire their own, as well as in a flipped-classroom setting. We do both at Berkeley.

The lecturelets are organized into YouTube playlists, one playlist per chapter, and are captioned in American English. Volunteer submissions of captions (.srt files) in other languages are *most welcome!*

***YouTube playlists for videos recorded in Fall 2023:***

* [Chapter 1](https://www.youtube.com/playlist?list=PLeMMGxq3FPxiCtrNMxkR10r3WxfNwRA_E) Introduction to Software as a Service, Agile Development, and Cloud Computing
* [Chapter 2](https://www.youtube.com/playlist?list=PLeMMGxq3FPxi172l51zkD85nxzBLIAMy8) How to Learn a New Language
* [Chapter 3](https://youtube.com/playlist?list=PLeMMGxq3FPxjMfAaytAuUvsa5A2yCvibq\&si=uWTe7xyYSKoj34tx) SaaS Application Architecture: Microservices, APIs, and REST
* [Chapter 4](https://www.youtube.com/playlist?list=PLeMMGxq3FPxg1K_1ijLSPKxUWmmS4pz5p) SaaS Framework: Rails as a Model--View--Controller Framework (Didactic content)
  * [Chapter 4 Rails Basics](https://www.youtube.com/playlist?list=PLeMMGxq3FPxhiyXK3xRPS0zlQ6jHiCYHZ): Additional walkthroughs and livecoding demos
* [Chapter 5](https://www.youtube.com/playlist?list=PLeMMGxq3FPxhqh_fJUuNHiu9ePUzNmzIW) SaaS Framework: Advanced Programming Abstractions for SaaS
* [Chapter 6](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgU93UaK7drCX1c1QePZ7yi) Mobile and Desktop SaaS Clients: JavaScript Introduction
* [Chapter 7](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjutjgtih7vy2n1Lfi5icBd) Requirements: BDD and User Stories
* [Chapter 8](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgx3HKXKKXltEYniCXmOsdk) Testing: Test-Driven Development
* [Chapter 9](https://www.youtube.com/playlist?list=PLeMMGxq3FPxhQAtcrOCca-0Oj1NfhM3KI) Software Maintenance: Enhancing Legacy Software Using Refactoring and Agile Methods
* [Chapter 10](https://www.youtube.com/playlist?list=PLeMMGxq3FPxiE4l8UYuacXeYkrL9t0aYH) Agile Teams
* [Chapter 11](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgbMJv_sS1_H0WIXLdevqES) Design Patterns for SaaS Apps
* [Chapter 12](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgrqiyguLsMBHsDc6wcWq0a) Dev/Ops

**Self-Check Questions to Accompany Lecturelets**

TBD

**Lecture Slides**

Most of the slides used in the lectures are available as [Google Slides](https://drive.google.com/drive/folders/1YJpubP97LxvfJYLYXsq4JxQ-TQIWZO2f?usp=sharing) (you must be a registered instructor to access the folder—see the [Welcome](/) page). Again, there have been a few updates, and a few decks that need updating, but these may be useful as a starting point.

**SaaS TV interviews**

This [playlist](https://youtube.com/playlist?list=PLeMMGxq3FPxiFmDh98ysUroIhmkewfO4i) contains interviews with a number of working engineers who do ESaaS, giving weight and credibility to some of the topics covered in the syllabus. These are uncaptioned; captioned submissions welcome.

**Short videos about the course**

This [playlist](https://youtube.com/playlist?list=PLeMMGxq3FPxjyflGWxsutxceHqBHk7Oyc) includes (as of 2022) the following **uncaptioned** videos (caption submissions welcome):

* a welcome from Armando Fox and Dave Patterson
* an interview with a customer of our student projects created in the course
* an exhortation from Google's VP of Engineering about the importance of teamwork in software engineering
* a short piece on the role of GitHub and open source in software engineering team projects and collaboration in this course

***Archival YouTube playlists for original (now obsolete) videos:***

* [Chapter 1](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjcFZVmvkuc5tW2HtTkqlgP) Introduction to Software as a Service, Agile Development, and Cloud Computing
* [Chapter 2](https://www.youtube.com/playlist?list=PLeMMGxq3FPxh7_76PotmzGsZGM8Q1Vthl) How to Learn a New Language
* [Chapter 3](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgAcnQh5eHqTfO4Ucs5JORw) SaaS Application Architecture: Microservices, APIs, and REST
* [Chapter 4](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjBbeB_aZ4L8Wo91rEds_GD) SaaS Framework: Rails as a Model--View--Controller Framework
* [Chapter 5](https://www.youtube.com/playlist?list=PLeMMGxq3FPxgeKHXxYOkV4JKCbRg5gWpg) SaaS Framework: Advanced Programming Abstractions for SaaS
* [Chapter 6](https://www.youtube.com/playlist?list=PLeMMGxq3FPxghXCpd4twByvWG6RKWcxHN) Mobile and Desktop SaaS Clients: JavaScript Introduction
* [Chapter 7](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjbdVAkCU99UumJDWuLvg-l) Requirements: BDD and User Stories
* [Chapter 8](https://www.youtube.com/playlist?list=PLeMMGxq3FPxh_gCC98WbEfpRt5UBFrjAT) Testing: Test-Driven Development
* [Chapter 9](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjSeso1JXLqmqXPDB0Ka-L3) Software Maintenance: Enhancing Legacy Software Using Refactoring and Agile Methods
* [Chapter 10](https://www.youtube.com/playlist?list=PLeMMGxq3FPxjO97PniMI2kfRyR4_MnT3t) Agile Teams
* [Chapter 11](https://www.youtube.com/playlist?list=PLeMMGxq3FPxhmpbjhY8yurexXmuF4Fvai) Design Patterns for SaaS Apps
* [Chapter 12](https://www.youtube.com/playlist?list=PLeMMGxq3FPxh_vJS0_FVhudNMJ2cA95cH) Dev/Ops


# PrairieLearn: Practice Problems, Competency Questions, Quizzes, Exams

As of 2021, we’ve moved all summative assessments (quizzes/exams) and all non-CHIPS formative assessments (practice problems, practice questions not involving code-writing) to use the [PrairieLearn](https://prairielearn.org) (PL) assessment authoring system. Besides allowing us to create rich interactive exercises, PL allows randomizing elements of the questions, making them suitable for summative assessments as well as practice.

PL is open source and you can download and run it yourself (not trivial), or contact the nice folks at [PrairieLearn.com](https://prairielearn.com) to host it for you; they will usually offer a free trial period so you can try out the system for a semester before using it. **Disclaimer:** While we love PrairieLearn, we have no formal connection to PL so you'll need to contact them directly for support (except, of course, for bugs in the ESaaS questions themselves).

## How to get the ESaaS PrairieLearn content

See below for how PL organizes content for a course. In short, you'll need a GitHub repo representing your course, which you'll populate with questions and assessments. If you're getting your free trial from PrairieLearn.com, there's a "request course creation" button on their site that creates a repo there. If you're running PrairieLearn yourself (you'll need to get your IT folks involved here), you'll create a GitHub repo that you own from which you'll publish your course.

In either case, you have a couple of ways to get access:

1. To preview the questions as a student would see them, PrairieLearn has a *question sharing* feature  we can use. A subset of the questions in our question bank are linked from the textbook as *competencies*; email Armando for a document containing links from each Competency
2. Email  Armando for a Zipfile that you can unpack that includes *most* of our PL questions. (Our repo includes at least some questions we'd like to keep private so they don't escape into the wild, and a few files containing Berkeley-specific information, so we extract a subset of the questions to send you.) Note that the PrairieLearn question format isn't particularly amenable to generating printed quizzes, so if that is your goal, you might find it easier to preview the questions above and adapt them as you see fit.

## Competency questions from textbook

The textbook has been augmented with competencies at the end of each section, and a subset of these are linked to PrairieLearn questions that test the competency. You and your students can preview the questions—that is, attempt to answer them and get the autograder feedback—for free using the PrairieLearn *question sharing* feature, for which all you need is the "magic sharing link" for each question. Email Armando to get a document of these links. (Note that this relies on security-through-obscurity: any student who has the link can access the questions and autograder.)

## Overview of ESaaS Content in PL

The `questions/` subdirectory in the PL archive contains questions organized by chapter of the textbook. There are 3 broad categories of question types:

1. "Simple" questions that could be made to work with other (non-PL) platforms, such as:
   * multiple-choice or select-all-that-apply questions. In a few cases, the answer choices will be randomized in the sense that the choices displayed to the student (both the correct answer(s) and distractors) are drawn from a longer list of correct answers and distractors.
   * “Put these steps in order” questions, in which the students drag-and-drop a set of steps into a correct partial or total order. In a few cases, the steps shown will be a subset drawn from a longer list of possible steps (and distractors).
   * Short-answer/fill-in-blank/numeric answer questions, in which the answer must match a regular expression or fall within a numeric error of a correct answer. In a few cases, the specific numeric or string parameters in the question will be randomized.
2. **Practice questions** for topics such as constructing and parsing routes, writing regular expressions, and so on. Many of these questions feature randomizatio&#x6E;*.* For example, a question on database joins and Cartesian products will generate a set of random-but-plausible data constructed from a large corpus of real data each time the question is repeated. These could in principle be used on exams or quizzes to take advantage of the randomization, but are also excellent for practice.
3. **“Artisan” exam questions** that are more involved and appropriate for longer exams, but have little or no randomization.

## Connecting questions to competencies

Starting with book version 2.0b9, the end of each subsection in the book includes one or more Self-Checks, for the student to verify that they understood the main points of the section, and sometimes one or more Competencies, specific skills that the student should be able to demonstrate. Here is an example from the end of section 9.7, comparing the maintenance processes for plan-and-document projects vs. agile projects:

<figure><img src="/files/c7todBDySHBB0Ct6oFyQ" alt=""><figcaption><p>Unlike the self-checks, most of the Competencies are linked to PrairieLearn questions.</p></figcaption></figure>

The difference is that most Competencies have an associated question in the question bank, either in PrairieLearn format or in the form of an open-ended question. The file `competencies_map.<bookversion>.html` at the top level of the PL archive maps a subset of the competencies listed in the book to one or more PL question IDs (QIDs) that check that competency. We don't claim that the given questions are an exhaustive test of the competency, but it's somewhere to start to make sure you're getting the coverage you want on your summative assessments.

Some of these questions are particularly well suited to "skills building" because there's enough randomness that students can generate many question instances and get instant feedback while practicing the skill repeatedly. For example, the questions on regular expressions are like this. Using the PL UI, search for questions tagged "practice" to find more of these.

## Per-Chapter Quizzes in PL

In the directory `courseInstances/TEMPLATE/assessments`, you'll find subdirectories `ModuleQuiz01`, etc. each of which contains a collection of suggested questions for reviewing that chapter grouped into an `infoAssessment.json` file. These are only suggestions!


# Codio: CHIPS

By far the recommended way to do the programming and other assignments (CHIPS, see below) is the [Codio](https://codio.com/esaas) IDE. Codio includes the correct versions of all the necessary tools and libraries; the programming assignments; the autograders; "scaffolding" for the programming assignments woven into the assignments themselves;  and even the textbook sections correctly interleaved with the assignments, including the "self check" questions in the textbook.

We are working on [creating coding exams in Codio](/chips/coding-exams) (help welcome).

There is a modest fee to use Codio; it can be paid by the student or you can negotiate a classroom or site license directly. Codio is very enlightened about providing a limited number of "access codes" for students for whom paying the fee is a financial hardship. Contact your Codio rep and ask them for "bookstore codes," which students can then redeem using [this process](https://docs.codio.com/students/accessing-codio/paying.html#redeeming-code-from-campus-bookstore).

All in all, Codio have been extremely supportive in helping to make teaching this material a low-friction experience. We're grateful for their help and encourage you to adopt the platform, as all future innovation around ESaaS programming assignments will use this platform.

## Codio course organization

There is a Codio course called **ESaaS 2020 (TEMPLATE)** that is a parent of any given semester's offering of CS(W)169(A) and also the parent of all the edX courses. It may also be the parent of other instructors' instances of the ESaaS course. (There are lots of ESaaS child courses owned by other instructors at other institutions; you can only see the courses you own.)

Changes made in the TEMPLATE course can be "pulled" into children, but not vice versa. So "permanent" changes/fixes to course materials should be made in the TEMPLATE course and then disseminated.

{% hint style="info" %}
(Because a child course is allowed to contain only a subset of the parent course, each of the three edX courses is a separate child course owned by Berkeley EECS, with 2/3 of the content removed.)
{% endhint %}

## Caveat about configuring LTI for Codio

If you're using another LMS to communicate with Codio via LTI, be aware that Codio autograder grades will *not* be reported back to the LMS until the student clicks "Mark as complete" in Codio, and in our experience students often forget to do this and are then confused when all their tests pass in Codio but the LMS shows a zero (or no grade) for the assignment. "Mark complete" also has the effect of making that assignment read-only for the student, and if they want to modify their solution before the deadline, you have to manually re-open the assignment for them. An alternative is to use the Codio setting "Disable 'Mark as Complete'" for each assignment, and then as an instructor, use "Mark all as completed" after the assignment deadline passes; then the student can modify the assignment right up until the deadline, and whatever grade they have at that instant becomes the recorded (via LTI) grade when you click Mark All as Completed.

## Modifying or creating an assignment

To change the **content of a CHIP,** see the [Git repo](https://github.com/saasbook/chips).

## Changing the stack used by an assignment

In general, we **do not use** the "certified" Codio stacks. As of Spring 2021, use the stack called "**ESaaS with Gradescope and rvm wrapper**", which is also the default stack for the course.

{% hint style="info" %}
Remember that a stack's Ruby version and Bundler version (at least) need to be consistent with the `Gemfile` and `Gemfile.lock` for the assignment(s) using that stack, or it will create extra steps when starting the assignment.
{% endhint %}

{% hint style="info" %}
Codio stacks are maintained as Ansible playbooks. [This video](https://youtu.be/VWNX0VN0vjE) steps through how to create a stack on Codio from an existing Ansible playbook.
{% endhint %}

To change the **stack used by a CHIP,** it's easier to do it interactively in Codio. If you change the TEMPLATE course, the changes can easily be made available to child courses; if you change a child course, the changes will only be in that course.

1. In the TEMPLATE course or child course, open the desired assignment.&#x20;
2. Manually make any changes to the stack using `sudo apt-get install`, etc.&#x20;
3. When ready, go to **Project > Stack… > Create New…** This will create a new stack based on the existing state of the VM. The stack does not capture stuff in the `.guides` folder or the student-visible `~codio` folder, just the system stack.&#x20;
4. If changing the **TEMPLATE** course, indicate that the new stack should be owned by the `Berkeley EECS` org.&#x20;
5. Once stack creation is done, go to **Project > Stack > Settings…** and ensure this new stack is selected as the project's stack, and that **Use Latest Version** is selected, so that all assignments using that stack will use the latest version.
6. Select **Education > Publish**.

{% hint style="info" %}
For students who have started the assignment - when the stack is modified, student code will not be affected. Specifically, any files outside of the `.guides` directory (which is invisible to students) will be unaffected. But if they installed other stuff using `sudo` etc. in their stack, that **will** be wiped if the stack is changed.
{% endhint %}

## Distributing changes to child courses

1. Go back to Courses list and select the current semester's offering of the course (or whichever course(s) you want to distribute the changes to).&#x20;
2. Scroll down to the CHIPS whose stack you changed and click the "Pull" icon—this updates the staged assignment from the parent course.
3. Once pull is done, click Publish. (NOTE: If the assignment has never been opened before in this child course, you may need to open it first, then return to this page and Publish.)&#x20;
4. Repeat for any other child courses, e.g. the edX MOOCs, to update them.

## Optional: Notify Others

Notify Elise Deitrick at Codio in case she wants to announce to other instructors (owners of child courses) in case they want to pull in the changes.

Notify **<esaas-instructors@googlegroups.com>** that the assignment(s) have been updated to use a new stack. They will need to "pull" from the TEMPLATE course if they want those changes in their own course.


# SaaS In the News

This page collects links to interesting articles relevant to the course topics, organized by which chapter/topic each is relevant to and sorted most-recent-first within each topic. Links to articles, videos, etc. does not imply endorsement by us of their points of view, nor do we have any formal connection to the authors unless otherwise stated; we just think these are relevant to software engineering and useful in helping to put in context some of the material taught in the course.

Evergreen articles—generally relevant and not tied to a specific event—have *<mark style="color:green;">**bold italic green titles**</mark>***.**

## General

[The Unix Chainsaw](https://www.youtube.com/watch?v=ZQnyApKysg4) \[video]: a great explanation of why Unix command-line skills are so valuable for developers, and a great illustration of the "Unix philosophy" of combining small specialized tools. One of the examples is a mini-master-class in using the entire Unix environment as your IDE.

## 1 Introduction to Software as a Service, Agile Development, and Cloud Computing

*<mark style="color:green;">**October 2021:**</mark>* [Missouri (USA) state government goes after newspaper and computer science prof for revealing bug in state-run software that exposes public school teachers' personal information](https://www.nytimes.com/2021/10/15/us/missouri-st-louis-post-teachers-hack.html) (Followup article in ArsTechnica: [Viewing website HTML code is not illegal or “hacking,” prof. tells Missouri gov.](https://arstechnica.com/tech-policy/2021/10/viewing-website-html-code-is-not-illegal-or-hacking-prof-tells-missouri-gov)) Gov. Mike Parson of Missouri has asked for a criminal investigation of a St. Louis Post-Dispatch reporter who told the state that a website revealed teachers’ Social Security numbers. In fact, the only thing the reporter did was view the source of a publicly visible Web site and notice that Social Security numbers were present in cleartext in the source. This story underscores the importance of having public officials who either have some minimal competence with technology, or are inclined to hire and listen to staff aides who do.

*<mark style="color:green;">**November 2021:**</mark>* [Techie parents in Stockholm in trouble after building open-source app to replace crappy proprietary app for accessing school data](https://arstechnica.com/information-technology/2021/11/these-parents-built-a-school-app-then-the-city-called-the-cops/). The Swedish government spent years and millions of dollars to have 5 companies build national platform for schools (combination of LMS, registration info, grades, parent portal, student portal...) The apps are buggy and get awful reviews from parents and students, and lots of complaints (since they're the only way parents can get info about how their kids are doing in school, etc.) Some techie parents reverse engineer the apps' server APIs and create their own open-source mobile apps, which are widely praised, as well as a well-designed publicly-accessible API shim over the original crappy undocumented API. The government cracks down and launches a national investigation around "possble illegal access to data" and starts making deliberate breaking changes to APIs. The nation eventually comes to its senses and now there is an "official" decent API that anyone (with permission and API key) will be able to use to build similar apps.

*<mark style="color:green;">**June 2023:**</mark>* [How NASA Writes Space-Proof Code](https://www.youtube.com/watch?v=GWYhtksrmhE) \[video]. The ultimate plan-and-document organization writes code for systems that may be millions of miles away and/or unreachable when something goes wrong. How do they do it?

*<mark style="color:green;">**November 2023**</mark>*: [Why do mainframes still exist? What's inside one?](https://www.youtube.com/watch?v=ouAG4vXFORc) \[video] A theme of this class is that good design is about choices, and while SaaS+Agile+Cloud is a great choice for many apps, some apps have quite different requirements. This video, replete with technical detail, is a fascinating look at the latest IBM zSeries mainframes—their design, including AI acceleration hardware; redundancy and reliability; and the kinds of apps that need those affordances.

*<mark style="color:green;">**October 2023**</mark>*: [The IRS is rolling out its (new) free tax-filing tool, and surprisingly, it's great](https://www.fastcompany.com/91178532/the-irs-is-rolling-out-its-free-tax-filing-tool-to-30-million-americans-and-surprisingly-its-great). Chapter 1 of ESaaS tells the dismal story of the disastrous 2013 rollout of Healthcare.gov, the US Government's health insurance portal, which was to be a signature achievement of President Barack Obama's administration. We also presented some opinionated commentary about whether things might have turned out better if government software efforts were developed with more of the Agile practices in mind, rather than the BDUF approach that had characterized most government software procurement. Fast forward ten years, and I guess the government took our advice :-)  The Internal Revenue Service (the tax-collecting agency of the US Government) worked with the [US Digital Service](https://usds.gov) and with [18F](https://18f.gsa.gov), an organization founded by several Presidential Innovation Fellows during the Obama administration to modernize US Government IT by bringing in the best practices of private industry.  They followed some of the most important Agile practices: they allowed potential users to play with different mockups, observing their behavior and putting the best ideas into the prototype; they included the customer in continuous refinements of the design; they started with a small deployment to find and fix bugs and make improvements before scaling up. As a result, Direct File processed more than 140,000 returns during its first year, exceeding its goal of 100,000, and suffered no outages in the process. (By comparison, H\&R Block, one of the largest private-sector providers of tax services, suffered some outages on tax day.) A General Services Administration survey found that more than 90% of users who tried Direct File rated it “excellent” or “above average,” and  86% of users said the experience increased their trust in the IRS, a government agency not traditionally known for high user confidence or loyalty.

*<mark style="color:green;">**December 2023**</mark>*: [What Do ChatGPT and AI-based Automatic Program Generation Mean for the Future of Software?](https://cacm.acm.org/blogcacm/what-do-chatgpt-and-ai-based-automatic-program-generation-mean-for-the-future-of-software/) Distinguished software engineer and professor Bertrand Meyer argues that while LLMs will generate better and better code, some of the key activities that differentiate *software engineering* from *programming,* such as requirements generation, specification, and verification, will only increase in importance.

*<mark style="color:green;">**December 2024**</mark>*: Addy Osmani [observes](https://addyo.substack.com/p/the-70-problem-hard-truths-about) (as have many others) that experienced and novice developers use generative AI in very different ways to assist in software development, often with very different outcomes.

*<mark style="color:green;">**June 2025**</mark>*: IRS Direct File has been [released](https://www.fsf.org/blogs/community/irs-direct-file-released-as-free-software)  on[ GitHub as public domain](https://github.com/IRS-Public/direct-file) software. This SaaS project was a triumph of collaboration between 18F and the US Digital Service (see "October 2023" item above), allowing US taxpayers access to a free SaaS app to electronically file their taxes. After a successful pilot in 2024, it was rolled out to about half of all states, and user reactions were overwhelmingly positive. In 2025, the Trump administration disbanded the team that built the service and [announced it would be shut down](https://www.nytimes.com/2025/11/06/business/taxes-irs-direct-file.html?unlocked_article_code=1.zE8.8Rpp.DdCvReM69GcA\&smid=url-share). Some of the team  released it as public domain software in the hopes that it won't die.

## 2 How to Learn a New Language

## 3 SaaS Application Architecture: Microservices, APIs, and REST

*<mark style="color:green;">**September 2023**</mark>*: [Google's widely-opposed ad platform, "the privacy sandbox," launches in Chrome](https://arstechnica.com/gadgets/2023/09/googles-widely-opposed-ad-platform-the-privacy-sandbox-launches-in-chrome/). Cookies have a (well earned) bad reputation for being used to track users across websites, but rather than a tracking-free experience, Google has been pushing an alternative model that the Electronic Frontier Foundation calls "[a terrible idea](https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea)." But because it'll be built into Chrome, a lot of users will probably unknowingly opt in by default.

*<mark style="color:green;">**October 2025:**</mark>* [HATEOAS for Haunted Houses](https://www.sanfordtech.xyz/posts/hateoas-for-haunted-houses/). A case-study in using Hypermedia as the Engine of Application State (HATEOAS) architecture to build a flexible control system for a local haunted house on a tight delivery schedule. HATEOAS promotes a simple, streamlined, hypermedia-centric request-reply architecture that takes REST to heart: all the information necessary to understand and trigger whatever operations are available on which resources is readily available in a delivered hypermedia document, largely eliminating the need for API documentation or client-side rendering logic. While HTML is technically a hypermedia language, this article uses HTMX, a fairly clean and minimal extension to HTML that allows expressing common RESTful behaviors in declarative HTML with no application-specific JavaScript.

## 4 SaaS Framework: Rails as a Model--View--Controller Framework

## 5 SaaS Framework: Advanced Programming Abstractions for SaaS

## 6 Mobile and Desktop SaaS Clients: JavaScript Introduction

## 7 Requirements: BDD and User Stories

## 8 Testing: Test-Driven Development

February 2024: [Self-pay gas station pumps break across NZ as software can’t handle Leap Day](https://arstechnica.com/gadgets/2024/02/leap-year-glitch-broke-self-pay-pumps-across-new-zealand-for-over-10-hours/). We thought this was amusing since a very similar bug is used as the example of TDD and debugging (the leap year problem with Microsoft Zune music player).

## 9 Software Maintenance: Enhancing Legacy Software Using Refactoring and Agile Methods

*<mark style="color:green;">**February 2023**</mark>*: [The Airline Industry's Problem With Absolutely Ancient IT](https://www.youtube.com/watch?v=1-m_Jjse-cs) \[video]. The catastrophic meltdown of airlines at Christmas 2022, once the terrible weather had subsided, was largely an IT problem. Here's a lesson in what happens when legacy systems are ignored for too long rather than updated incrementally.

## 10 Agile Teams

## 11 Design Patterns for SaaS Apps

## 12 Dev/Ops

*<mark style="color:green;">**January 2019**</mark>*: [SQL Is No Excuse to Avoid Dev/Ops](https://cacm.acm.org/practice/sql-is-no-excuse-to-avoid-devops/). Besides busting the myth that "heavyweight" SQL databases (vs. NoSQL stores) somehow get in the way of agile deployment due to schema-management concerns, this practitioner-focused article basically walks through a feature-flagged, schema-versioned approach to agile dev/ops very close to the one espoused by ESaaS, including how to test such changes in CI before production deployment.

*<mark style="color:green;">**November 2023:**</mark>* [Highly invasive backdoor snuck into open source packages targets developers. ](https://arstechnica.com/security/2023/11/developers-targeted-with-malware-that-monitors-their-every-move/)Typical modern software projects rely on hundreds of open source libraries. But how do you know there isn't malicious code lurking in those libraries? (See also April 2026 article about WordPress plugins, below)

*<mark style="color:green;">**July 2024:**</mark>* [How Crowdstrike brought worldwide IT to a halt](https://www.youtube.com/watch?v=wAzEJxOo1ts) \[video]. A good explanation by a Windows developer of what specific properties of this anti-malware product allowed it to compromise so many systems in such a thorough way.&#x20;

*<mark style="color:green;">**April 2026:**</mark>* [Somebody bought 30 WordPress plugins and planted a backdoor in all of them](https://anchor.host/someone-bought-30-wordpress-plugins-and-planted-a-backdoor-in-all-of-them/). Apparently [wordpress.org](https://wordpress.org) used to do some level of code review before listing a plugin on the official WordPress  catalog, and they are no longer doing so (or doing it sloppily). As a result, a company that was looking to cash out on some (legitimate) plug-ins it had developed sold all of them to an unidentified new developer, who planted backdoors in them and distributed the "update" to all the users who had downloaded the original (legitimate) plug-ins. It's a lesson on the role of trust in "app store"-like scenarios, and the tension between Apple's highly regulated iOS/Mac App Store and Google's much less regulated Android/Google Play store.<br>


# CHIPS (Programming assignments)

To complement the Content-Oriented Didactic (COD) materials such as the book and lectures, CHIPS (Coding & Hands-on Integrated Projects) provide hands-on skills practice and are keyed to specific sections in the book. This section describes how to use them with Codio. The [book's website](http://www.saasbook.info/instructors) has other options if you don't wish to use Codio, but we have pretty extensive automated workflows that are optimized for Codio, for publishing both the book content itself and these CHIPS along with their autograders.

If you're using Codio, all you really need to know is how the CHIPS work—see below. If you want to use the CHIPS outside of Codio, or contribute to their development, look at the README in the CHIPS [repo](https://github.com/saasbook/chips) (visible to [registered instructors](https://www.saasbook.info/instructors)).

Here's a quick summary of the assignments, presented in the order in which they appear in the [ESaaS textbook](http://www.saasbook.info). Following the summary are details on how to edit and dry-run each assignment, and any noteworthy caveats. There are three types, as indicated in the table below:

1. **(A)utograded using Codio:** The single repo `saasbook/chips` includes everything needed to generate (a) student-facing starter code repo, (b) Codio autograder (including files that are hidden from students when they use Codio), (c) Codio "Guides" panels to walk the student through the assignments, (d) reference solution. That repo's README includes generic instructions for how to edit, test, and deploy Codio-autograder-based CHIPS. Some CHIPS also include files for manually configuring [Gradescope](https://gradescope.com)-based autograding, but Gradescope is no longer officially supported, so use those files at your own risk.
2. **(P)rairieLearn autograding:** The questions are done in the PrairieLearn assessment authoring system and have autograders there.
3. **(S)elf-graded:** CHIPS involves coding, but rather than an autograder, students run tests themselves that are included in the student-facing code repos. It's up to you if you want to verify that they've done so (e.g. by having them submit a screenshot, etc.)
4. **(C)omprehension-based with some autograding:** CHIPS involves minimal or no coding, but rather performing some tasks and answering self-check questions about them. The tasks can be performed in the Codio IDE's terminal window, and in some cases the questions are built into the Codio version of the assignment as unlimited-attempt selected-response/short-answer questions.

The relative effort of each CHIPS is indicated by one bullet (1-2 hours of effort), two bullets (2-3 hours), or three bullets (a potentially multi-day assignment). Here are the book sections in which the CHIPS occur, along with their effort ratings.

<table><thead><tr><th width="90">Sec.#</th><th width="62">Type</th><th width="65">Effort</th><th>Description</th></tr></thead><tbody><tr><td>2.5</td><td><a href="https://github.com/saasbook/hw-ruby-intro-ci">A</a></td><td>••</td><td><a href="https://github.com/saasbook/hw-ruby-intro">Ruby Intro</a>: gentle intro to Ruby idioms, including running instructor-provided unit tests to check your answers</td></tr><tr><td>3.3</td><td>C</td><td>•</td><td> <a href="https://github.com/saasbook/hw-http-intro">HTTP and URI</a>s: intro to HTTP requests, URIs, and cookies, using <code>curl</code> and <code>netcat</code> to see raw data, using the <a href="https://esaas-cookie-demo.herokuapp.com">esaas-cookie-demo app</a> (<a href="https://github.com/saasbook/esaas-cookie-demo">source</a>).</td></tr><tr><td>3.7</td><td><a href="https://github.com/saasbook/hw-sinatra-saas-wordguesser-ci">A</a></td><td>•••</td><td> <a href="https://github.com/saasbook/hw-sinatra-saas-wordguesser">Create and Deploy a Simple SaaS App</a>: de-mystifies the creation of a SaaS app (a simple word-guessing game using Sinatra) including use of an external service, and how to think about RESTfully "wrapping" application logic in SaaS.</td></tr><tr><td>4.3</td><td>S</td><td>•</td><td> <a href="https://github.com/saasbook/hw-activerecord-practice">ActiveRecord Basics</a>: write ActiveRecord queries against a provided seeded database.</td></tr><tr><td>4.5</td><td>S</td><td>•</td><td> <a href="https://rails-routing-practice.herokuapp.com">Rails Routes</a> (self-graded): not actually a homework assignment, but a simple app that lets students enter syntactically valid Rails routes and understand the RESTful routes that Rails would generate for them.</td></tr><tr><td>4.7</td><td>C</td><td>••</td><td> <a href="https://github.com/saasbook/hw-rails-wordguesser">Word Guesser on Rails</a> (comprehension with <a href="https://github.com/saasbook/hw-rails-wordguesser-ci">reference solutions</a>): use the same Word Guesser game logic and Cucumber scenarios as CHIPS 3.7, but scaffolds a walkthrough of how to deploy the app with Rails instead of Sinatra, as an on-ramp to understanding the complex Rails framework.</td></tr><tr><td>4.9</td><td>S</td><td>•••</td><td> <a href="https://github.com/saasbook/hw-hello-rails">Hello Rails</a> (self-graded): create a brand-new Rails app (RottenPotatoes) from scratch, including routes, database setup, using the debugger, and deploying to Heroku.</td></tr><tr><td>5.3</td><td><a href="https://github.com/saasbook/hw-rails-intro-ci">A</a></td><td>•••</td><td> <a href="https://github.com/saasbook/hw-rails-intro">Rails Intro</a>: enhance RottenPotatoes to filter and sort movie lists.</td></tr><tr><td>5.7</td><td></td><td></td><td>Associations and SSO/WebAuthn login (TBD: not finished yet)</td></tr><tr><td>6.9</td><td></td><td></td><td>AJAX Enhancements to RottenPotatoes (TBD: not finished yet)</td></tr><tr><td>7.7</td><td><a href="https://github.com/saasbook/hw-bdd-cucumber-ci">A</a></td><td>•••</td><td> <a href="https://github.com/saasbook/hw-bdd-cucumber">Intro to BDD and Cucumber</a> (): write features to test happy and sad paths of RottenPotatoes.</td></tr><tr><td>7.9</td><td></td><td>••</td><td>BDD for New Feature: write scenarios and then backfill the code to make them pass, using BDD to drive the code for a new RottenPotatoes feature "Find movies with same director." Another goal is to achieve a threshold level of C1 coverage using SimpleCov.</td></tr><tr><td>8.5*</td><td>P</td><td>••</td><td> <a href="https://github.com/saasbook/hw-tdd-rspec">Intro to RSpec</a>: Introduction to RSpec test writing, including the use of doubles, before-blocks, and the arrange/act/assert pattern, using Faded Parsons Problems.  *This CHIP is part of the shared PrairieLearn question collection, rather than being in the <code>saasbook/chips</code> repo.</td></tr><tr><td>10.5</td><td>A</td><td><strong>!</strong></td><td>Agile Iterations Two (or more) full iterations of Agile adding features to an existing (legacy) app. See the separate section on CHIPS 10.5.</td></tr><tr><td>12.8</td><td></td><td>••</td><td> <a href="https://github.com/saasbook/hw-indices-performance">Exploiting Caching and Indices</a>: improve the performance of RottenPotatoes by adding database indices to speed up key queries.</td></tr></tbody></table>

### Optional additional CHIPS (not referenced in textbook)

* [Oracle of Bacon](https://github.com/saasbook/hw-oracle-of-bacon): Build a simple command-line app that uses external services in a SOA, including parsing XML responses.
* [Design Review](https://github.com/saasbook/hw-design-review): We use this in the project portion of the course. This is not a programming assignment but rather a 3-part scaffolded process for doing design reviews and technical presentations. (Each part can be used more or less independently.) It is intended to be used in conjunction with student teams doing their own open-ended projects, so no code is provided. In part 1 (Design Review), teams are paired up and each team evaluates the other's design and gives feedback on possible improvements. In part 2 (Presentation), teams give technical presentations about the design review; these are peer-evaluated (or instructor-evaluated) according to a provided rubric. In part 3 (Handoff), teams modify their repos as needed to ensure the project is easy for another team to pick up and continue working on.


# Exercises for Flipped Classroom

The [courseware repo](https://github.com/saasbook/courseware) (public, but for some links you need to be a member of either "ESaaS instructors" (read only) or "CS169 GSIs" (read/write)) has lots of worksheets, interactive activities, etc. with instructor-facing README files and organized by chapter of the book.

* `courseware/flipped-demos` includes a variety of livecoding demos with instructor support materials, such as prompting questions and a "script" for doing the livecoding.
* `courseware/discussion` contains worksheets, solutions, and code grouped by each module, suitable for use in hands-on small-section classes or for self-learning.
* `courseware/practice-exams` contains midterms from UC Berkeley and others using the materials that are suitable as practice exams.


# Additional Materials

Your students may also find the following external tutorials and resources helpful. *Note: This list is not regularly curated, so you should vet these yourself before relying on them. At the time they were added, they passed our vetting, but some of these have been on the list a long time!*

Resource links that are highlighted are specifically recommended by the book’s authors.<br>

|                                  | **Basic/Beginner Tutorials: Get started fast**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | **Going Further**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | **Reference/cheatsheets**                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ruby                             | <ul><li><a href="http://tryruby.org/">tryruby.org</a><br></li><li><a href="http://codecademy.com/tracks/ruby">codecademy.com</a></li></ul>                                                                                                                                                                                                                                                                                                                                                                                                                                    | <ul><li><a href="http://rubymonk.com/">rubymonk.com</a></li><li><a href="https://www.codeschool.com/courses/ruby-bits">code school ruby-bits</a> (starts free - later paid)</li><li><a href="http://www.codewars.com/kata/search/ruby?q=&#x26;r%5B%5D=-8&#x26;r%5B%5D=-7&#x26;r%5B%5D=-6&#x26;beta=false">codewars Ruby kata</a></li><li><a href="http://rubykoans.com/">rubykoans.com</a></li></ul>                                                                                                                            | <ul><li><a href="https://github.com/styleguide/ruby">Ruby Style Guide</a></li><li><a href="http://www.zenspider.com/Languages/Ruby/QuickRef.html">Ruby</a> cheat sheet</li></ul>                                                                                                                                                                                                                     |
| <p> <br><br>Rails</p>            | <ul><li><a href="http://ruby.railstutorial.org/">Michael Hartl Tutorial</a></li><li><a href="http://bundler.io">Bundler intro</a></li><li><a href="http://viget.com/extend/bundler-best-practices">Bundler best practices</a></li><li><a href="https://www.codeschool.com/courses/rails-for-zombies-redux">Rails for Zombies (intro free)</a></li></ul>                                                                                                                                                                                                                       | <ul><li><a href="http://appletree.or.kr/quick_reference_cards/Ruby-Ruby_on_Rails/rails-migrations.pdf">Migrations</a> cheat sheet</li><li><a href="http://slash7.com/cheats/form_helpers.pdf">Rails form helpers</a> cheat sheet</li></ul>                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                      |
| HTML & CSS                       | <ul><li><a href="https://developer.mozilla.org/en-US/docs/Learn/HTML">Learn HTML</a> (Mozilla Foundation). We recommend just doing the section on “HTML—Structuring the Web.”</li><li><a href="https://medium.freecodecamp.org/learn-bootstrap-4-in-30-minute-by-building-a-landing-page-website-guide-for-beginners-f64e03833f33">Bootstrap 4 in 30 Minutes</a> (FreeCodeCamp)</li><li><a href="http://codecademy.com/tracks/web">codecademy.com</a> Learn HTML</li><li><a href="https://www.codeavengers.com/profile#html-css">CodeAvengers HTML/CSS tutorial</a></li></ul> | <p><em>Once you know the basics of HTML and CSS:</em><br></p><ul><li><a href="https://developer.mozilla.org/en-US/docs/Learn/CSS">Learn CSS</a> (Mozilla Foundation) if you want to customize your CSS layouts</li><li><a href="http://flukeout.github.io/">CSS Diner</a>: practice CSS interactively <br>in this whimsical environment (first 15 lessons or so should be enough)</li><li><a href="http://thimble.mozilla.org/">Mozilla Thimble</a> is a full cloud-based HTML+CSS interactive authoring environment.</li></ul> | <ul><li><a href="https://developer.mozilla.org/en-US/docs/HTML/HTML5">Mozilla Developer Network: HTML5</a></li><li><a href="https://bootstrapcreative.com/resources/bootstrap-3-css-classes-index/">Bootstrap cheat sheet</a></li><li><a href="http://www.w3.org/DOM/">Document Object Model (DOM)</a> </li><li><a href="http://www.addedbytes.com/cheat-sheets/css-cheat-sheet/">CSS</a> </li></ul> |
| Deployment, dev/ops, performance |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | <p> </p><ul><li><a href="https://developers.google.com/web/">Google Web Fundamentals</a>: towards fast, integrated, reliable, and engagin browser-based apps</li></ul>                                                                                                                                                                                                                                                                                                                                                          |                                                                                                                                                                                                                                                                                                                                                                                                      |
| Git, GitHub                      | <ul><li>The <a href="https://github.com/jlord/git-it-electron">git-it interactive tutorial</a></li><li><a href="http://try.github.com">try.github.com</a></li><li><a href="http://www.youtube.com/GitHubGuides">GitHubGuides</a></li></ul>                                                                                                                                                                                                                                                                                                                                    | <ul><li><a href="http://gitimmersion.com">GitImmersion</a></li><li><a href="http://www.eecs.harvard.edu/~cduan/technical/git/">Understanding Git Conceptually</a></li><li><a href="https://www.udacity.com/course/ud775">Udacity Git Course</a></li><li><a href="http://eagain.net/articles/git-for-computer-scientists/">Git for Computer Scientists</a></li><li><a href="http://www-cs-students.stanford.edu/~blynn/gitmagic/">Git Magic</a> (advanced)</li></ul>                                                             | <ul><li><a href="http://gitready.com/beginner/2009/01/27/installing-git.html">Installing Git</a><br></li><li><a href="http://gitready.com/beginner/2009/01/21/pushing-and-pulling.html">Pushing and Pulling</a><br></li><li><a href="http://nathanj.github.com/gitguide/">An Illustrated Guide<br>to Git on Windows</a></li><li><a href="http://git-scm.com/book/">Pro Git</a> book</li></ul>        |
| JavaScript                       | <ul><li> <a href="http://hsablonniere.github.io/markleft/prezas/javascript-101.html#1.0"><http://hsablonniere.github.io/><br>markleft/prezas/javascript-101.html#1.0</a></li><li> <a href="https://www.codecademy.com/tracks/javascript"><https://www.codecademy.com/><br>tracks/javascript</a></li><li> <a href="http://freecodecamp.com/"><http://freecodecamp.com/></a> </li></ul>                                                                                                                                                                                         | <ul><li><a href="http://www.addedbytes.com/cheat-sheets/javascript-cheat-sheet/">JavaScript, DOM event handlers</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript"><https://developer.mozilla.org/en-US/docs/Web/JavaScript></a></li></ul>                                                                                                                                                                                                                                                           |                                                                                                                                                                                                                                                                                                                                                                                                      |
| Relational Databases             | <ul><li>Free mini-courses (\~30 mins each) from Stanford Database group: we recommend <a href="https://lagunita.stanford.edu/courses/DB/RDB/SelfPaced/about">Intro to Relational Databases</a> and <a href="https://lagunita.stanford.edu/courses/DB/RA/SelfPaced/about">Relational Algebra</a> as a minimum</li><li>Then learn a bit about <a href="https://lagunita.stanford.edu/courses/DB/SQL/SelfPaced/about">SQL Queries</a>, and you can then <a href="http://www.sqlteaching.com">practice SQL queries interactively</a></li></ul>                                    | <p><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | <ul><li><a href="http://www.sqlite.org/cli.html">SQLite3 command line</a> </li></ul>                                                                                                                                                                                                                                                                                                                 |
| RSpec                            |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <ul><li><a href="http://rspec.info/"><http://rspec.info/></a></li><li><a href="https://www.anchor.com.au/wp-content/uploads/rspec_cheatsheet_attributed.pdf">RSpec</a> cheat sheet</li></ul>                                                                                                                                                                                                         |
| Cucumber & Capybara              | <p><br></p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | <ul><li><a href="http://cukes.info/"><http://cukes.info/></a></li><li>LaunchAcademy <a href="https://www.launchacademy.com/codecabulary/learn-test-driven-development/rspec/capybara-cheat-sheet">Capybara cheatsheet</a></li></ul>                                                                                                                                                                  |

<br>

#### Free Screencasts  <a href="#toc-free-screencasts" id="toc-free-screencasts"></a>

* [Railscasts](http://railscasts.com/) - focuses on Rails-specific development issues
* [RailsLab](http://railslab.newrelic.com/) - focuses on Rails-specific operations/dev-ops issues&#x20;
* [BDDcasts](http://bddcasts.com/) specializes in BDD & Cucumber [TeachMeToCode](http://teachmetocode.com/)


# Legacy (non-PrairieLearn) Quizzes/Exam Questions

### Open ended questions for written exams ([instructor access only](https://www.saasbook.info/instructors))

[Open-ended response questions](https://github.com/saasbook/open-response-exam-questions) suitable for manual grading, along with reference solutions. Most of these have been converted to “Artisan” Exam Questions delivered through PrairieLearn.

### Multiple-choice/machine-gradable questions ([instructor access only](https://www.saasbook.info/instructors))

[Multiple choice questions](https://github.com/saasbook/csw169a-quizzes) grouped by textbook chapter. The [RuQL gem](https://github.com/saasbook/ruql) and its associated formatters let you export quiz questions to HTML/hardcopy, the Canvas LMS, and other quiz formats. This is a subset of all the questions in the PrairieLearn per-chapter quizzes.


# Coding Exams

{% hint style="warning" %}
We're in the process of moving these to Codio and will make them available as part of the Codio resources for instructors using Codio. The tools described below for running these exams are no longer supported, though the questions (and solutions) themselves may still be useful.
{% endhint %}

We've given exams where part of the exam is spent writing actual code. We have developed an infrastructure for doing this that allows students full read-only access to the Internet via Google's cache, so they can look up any existing information they want but cannot post a question or send email/messages to ask for the answers. However, you can also use these as homework assignments since they include test cases.

The repos contain solutions and test cases as well as questions; instructions are provided in each repo's `README-instructor.md` for creating just the student-facing part of the package.

In our setup, since the questions are multiple parts with later parts building on the results of earlier ones, each question subpart is associated with a hint and/or with the answer (i.e. code that if copy-pasted in the right place will solve that subpart). Students can "reveal" these hints if they accept a penalty of a substantial fraction of the points the exam question is worth. The hints are part of each repo; our [reveal](https://github.com/saasbook/reveal) script is installed in the exam environment (described in this paper to record which hints were used and calculate the penalty. We [found](https://dl.acm.org/authorize?N680629) that weaker students do not request more hints than stronger students, even though they would sometimes benefit more from doing so; weaker students are more likely to request hints on lower-scoring coding questions than higher-scoring ones; and all students are equally well able to use hints once provided.

* [Interview Scheduler](https://github.com/saasbook/exam-interviewscheduler-associations): Modify an existing app to add the correct associations among Interviews, Candidates, and Recruiters. Factor out some common code among the models and mix it back in, to DRY out the code. [Solutions](https://github.com/saasbook/exam-interviewscheduler-associations-ci)
* **(Incomplete)** [Ruby Iterators](https://github.com/saasbook/exam-ruby-iterators) Create Ruby iterators for a new `Matrix` class.
* [Can I Stream It?](https://github.com/saasbook/exam-rottenpotatoes-canistreamit) Enhance RottenPotatoes by adding a view that displays information retrieved from the `CanIStream.it` API.
* [Encryption Demo](https://github.com/saasbook/exam-encrypty) Create this [simple app](https://encrypty.herokuapp.com/) ([source](https://github.com/saasbook/encrypty)) that allows users to specify a key for symmetric encryption and to encrypt/decrypt text with that key.


# Philosophy: Why Agile? Why Ruby & Rails? etc.

This book is a hands on path through the bewildering array of methodologies, languages, tools, and artifact types that collectively make up "software engineering." The goal is to instill good software habits in students—testability, software architecture, modularity, and reusability—while providing them the gratification of building a working deployed artifact that they themselves (and their peers) would use and find compelling.

This Instructors Manual contains the authors' own materials as well as materials and hints contributed by other instructors, by our student teaching assistants, by our students, and more.

We also document the relationship between these materials and the 2013 ACM-IEEE Computer Society software engineering curriculum standard.

### Student Projects and Learning By Doing <a href="#student-projects-and-learning-by-doing-.unnumbered" id="student-projects-and-learning-by-doing-.unnumbered"></a>

The ACM/IEEE software engineering curriculum guidelines emphasize the value of an iterative approach in which students assess and revise their work continuously. We have found that students are much more likely to actually follow the Agile methodology because the Ruby on Rails tools, which we introduce in this book, make it easy and because the advice is genuinely helpful for their projects. We believe Agile offers learning skills that transfer to non-agile projects, should need arise. We even show how to use Agile techniques on legacy code that wasn't developed that way to begin with; that is, Agile is good for more than just writing new code from scratch.

The ACM/IEEE curriculum guidelines also highlight team projects as a critical learning mechanism for software engineering students. The experience of many instructors (including ourselves) is that students enjoy learning and using Agile in projects. Its iteration-based, short-planning-cycle approach is a great fit for the reality of crowded undergraduate schedules and fast-paced courses. Busy students will by nature procrastinate and then pull several all-nighters to get a demo cobbled together and working by the project deadline; Agile not only thwarts this tactic (since students are evaluated on progress being made each iteration) but in our experience actually leads to real progress using responsible practices on a more regular basis.

One of the CHIPS (Coding/Hands-on Integrated Projects) assignments takes students through a two-iteration "mini-project" using Agile/XP workflows. To help you run successful projects, the contains detailed suggestions for organizing and scheduling project milestones in a classroom course, and gives example rubrics for grading the projects based on both the artifacts produced and the processes used to produce them, taking full advantage of being able to do multiple iterations in a single course. We also survey each generation of students to determine what they learned from the projects and where they had difficulty; the distills these "habits of highly effective projects" based on several offerings of the course at UC Berkeley and elsewhere.

### Why Software as a Service?

To motivate students, it's helpful to use a platform that lets them create compelling apps. Today there are approximately 4.2 billion mobile phones deployed worldwide, or enough for 3 out of every 5 people on the planet; combined with the explosive growth of SaaS, we believe the future of software is "client + cloud" applications that are split between a tablet or smart phone and a cluster of servers to do heavy computation and persist data.

Therefore, both mobile applications for smart phones and tablets and Software as a Service (SaaS) for cloud computing are compelling targets for teaching students. As you can teach the principles with either target, given the time constraints of a single college course, we choose in favor of the platform with the most productive tools. Our experience is that it is no contest: the programming and testing frameworks for SaaS and cloud computing are dramatically more productive than those for mobile apps, and the client part of many SaaS apps can be adapted to mobile devices using the HTML/CSS/JavaScript skills learned in creating SaaS.

In addition, beyond the commercial promise of SaaS and the "hireability" of students who know how to create it, SaaS projects can be deployed inexpensively using public cloud computing, which means students' course artifacts are on display for the whole world to see. The exposure and "look what I made" factor of public deployment are hard to match.

### Why Emphasize Agile?

While the Agile Manifesto was considered controversial when released in 2001, today Agile is an accepted practice alongside disciplined or Plan-and-Document processes like Spiral or the Rational Unified Process. As the textbook explains, most software companies now use Agile in both large and small projects; we provide guidance on when Agile makes sense, and we conclude that it certainly makes sense for student projects in a cloud-computing-centric software engineering course. Within each iteration, we are able to address the major issues of the software lifecycle in microcosm—requirements elicitation from the customer, transforming requirements to user stories, driving the class-level architecture of the software using behavior-driven development, driving the implementation using test-driven development, and evaluating both unit/regression test coverage and acceptance/integration test results. That is, rather than first evaluating students on requirements gathering, then on good design, then on development and finally on test coverage and a working demo, *all* of these elements are evaluated on *every iteration*, encouraging the students to see the concepts and techniques as part of an integrated ongoing process rather than as isolated stages in a pipeline.

### Why Ruby and Rails? Why Not Java, C++, Python, or Scala?

We want students to understand that in the real world, programmers are rewarded not for the number of lines of code written or for how quickly they can "bash out" a feature, but for functionality delivered with high assurance of stability and while keeping the codebase beautiful and maintainable for continued growth. To many students, especially "hotshot" coders who come into a software engineering course with nontrivial programming experience, the methodologies and techniques we use to do this—design patterns, refactoring, test-first development, behavior-driven design—seem a strange and dubious use of time.

We have found that students are more likely to gradually embrace these practices if given the best possible tools to support the practices. The Rails community has created by far the most seamless, elegant, and comprehensive tool set to support Agile and XP, and the idea of constantly refining and inventing tools that support testing as well as helping produce beautiful application code is a distinguishing characteristic of the Ruby developer ecosystem. While learning Ruby and Rails will be new to most students, juniors and seniors seem to learn it without difficulty, and far superior tools outweigh the learning costs.

In other words, Agile and Rails were selected not because we expect them to dominate students' professional careers, but because their synergistic productivity allows us to fit several critical ideas and best practices into a single college course in the hope that students will later apply them to other methodologies, languages, and frameworks.

A common counterargument in academia is "Our curriculum already teaches language *X*, so upper-division courses should leverage that knowledge." We believe this approach optimizes for the wrong thing. First, software professionals are routinely expected to learn new languages by applying concepts from languages they already know, so "learning how to learn" new languages is a good skill to cultivate in class. Second, a language that makes it difficult to write and test beautiful and concise code is a poor vehicle for teaching those techniques, so the only investment being "leveraged" is syntactic knowledge, a hurdle surmounted with relative ease. Thus, even if our students never use Ruby again, they will have learned how to *reduce to practice* such important ideas as metaprogramming, higher-order programming, functional programming, and use of closures in the service of higher productivity and more maintainable code. We believe these skills will transfer to new languages, framework, and programming systems. Our survey of alumni of the course that led to this book suggests that our belief is well founded.

### Why Cucumber Instead of Capybara + RSpec?

Another debate in the Rails community is whether scenarios should be written using Cucumber or by writing RSpec tests that call Capybara directly or using a Ruby-level tool such as Steak.

Since we believe it's critical for students to engage the customer, we want to get them accustomed to the fact that code is not the right medium for collaborating with the customer, so we insist on Cucumber scenarios.

### Why Imperative Scenarios?

In 2011, Cucumber's designer Aslak Hellesøy removed from Cucumber the step definitions that allowed writing Cucumber imperative scenarios "out of the box." Hellesøy called these steps "training wheels" since they were mostly thin wrappers around Capybara's API, such as "When I click on..." calling Capybara's `click`, or thin wrappers around assertions, such as "Then I should see..." calling `expect`. His rationale for removing the "training wheels" was that Cucumber scenarios should be higher-level and declarative, essentially serving as a per-application domain-specific language for user stories, whereas the low-level step definitions encouraged a lower-level imperative style of scenario.

Although we agree with his motivation, we chose to introduce Cucumber using the low-level steps anyway, because we felt that imperative scenarios provide a "kinder, gentler" introduction to this new tool precisely because of the small conceptual leap ("I'm scripting the user's actions on the browser UI"). Once the low-level scenarios are written, they can be used as subroutines in declarative scenarios. Indeed, step definitions that call other step definitions are arguably easier to read, for the same reasons we advocate sticking to a single level of abstraction within a method (one of the SOFA principles in Chapter 9).

### Knowing What You Don’t Know

Each chapter of the book covers a topic that could itself be the subject of many books. The challenge for a textbook author is what to leave out. Or, put another way: if the chapter on TDD is the *only* material on TDD the student will ever encounter, what belongs in those \~40 pages? We describe enough to (hopefully) sketch the landscape and provide the basis for some learning by doing, but also indicate areas where much more detail would be possible, so that in the future the student will be aware that there is work in those areas (such as automatic test case generation and program synthesis) should they find themselves in situations where bringing those areas to bear would be useful.


# Classroom & Student Experience

The productivity afforded by the tools and services used in the course allows college students to experience the whole software life cycle repeatedly in a single course. A typical Berkeley undergraduate workload of four courses per term and a 50-hour work week gives students about 12 hours total per week per course, including lectures, labs, exams, and so forth. This works out to roughly 120 hours per quarter to 180 hours per semester, or just three to four weeks for a full-time developer! The productivity of Rails and its ecosystem of tools and the automation of tasks via services allow students to learn and practice software engineering fundamentals within the time budget of the classroom.

### Survey of Berkeley Alumni in Industry Activities

In 2014, shortly after adopting the book, we emailed a small sample of Berkeley undergraduates across two offerings of the course who were now working in the software industry. We wanted to know what development methodologies they were using, what software platform (cloud, shrinkwrapped software, etc.), what language(s), and the sizes of the teams they were in, if any. The following figure summarizes the responses. Just 22 of the 47 respondents had graduated, and just 19 had done significant software projects. The figures below show the results of their 26 software projects. We were surprised that Agile software development was so popular (68%) and that the cloud was such a popular platform (50%). Given that no language was used in more than 22% of the projects, our alumni must be using Agile in projects that use languages other than Ruby or Python. All the class teams had four or five students, which happily matches the average team size from the survey.

![](/files/v1SGxFhT4BXuhp7mq5IL)

The next figure shows these same students' ranking of the topics in the book in terms of usefulness in their industrial projects. Most students agreed that the concepts in the course were useful in their jobs. Once again, we were pleased to see that these ideas were still being used, even in industrial projects that did not rely on Agile or on Rails. The two lower ranked topics were Lo-Fi User Interface Mockups, which makes sense since few developers work on the UI of a user-facing project, and Velocity, as progress can be measured in other ways in industry.

![](/files/tkUAKO0DAB2dshvXULKv)

Although a small sample and not a conclusive user study, we think our survey offers at least anecdotal evidence that people who study this material continue to use successful software development techniques in later software projects of all kinds.

### Conclusion: Perspectives on Course from Three Sets of Stakeholders

Overall, our experience has been that all three stakeholders have enjoyed using the material:

* Students like it because they get the pride of accomplishment in shipping code that works and is used by people other than their instructors, plus they get experience that can help land internships or jobs.
* Instructors like it because students actually use what they hear in lecture, they can see how big computer science ideas genuinely improve productivity, and they use what they learn beyond the classroom. They also enjoy that the testing and code evaluation tools of Rails can help automatically grade interesting programming assignments. Autograding enables teaching the Agile lifecycle in a , thereby allowing thousands of students to learn the material at once.
* Colleagues in industry like it because it addresses several of their concerns. An example is this quote from a Google manager:

> I'd be far more likely to prefer graduates of this program than any other I've seen. As you know, we're not a Ruby shop, but I feel this is a good choice for the class to be able to get real features done. Java or C++ would take forever.


# Chapter Overviews

Here is a 1-paragraph overview of the main content-oriented didactics (COD) in each chapter, and the associated CHIPS or other materials for hands-on practice.

## 1. Introduction to Software as a Service, Agile Development, and Cloud Computing

We contrast SaaS with shrink-wrapped software, Agile with other development methodologies, and cloud computing with earlier models of provisioning computing, and describe the synergy among the three. SaaS/cloud/agile are not necessarily always superior, but the learner should understand when each is appropriate to use. We describe techniques that programmers have developed over time to improve their productivity, such as software reuse, conciseness, and rich tooling. We introduce the fundamental architectural concepts of cloud computing and mobile clients. Finally, we emphasize the importance of the maligned term "legacy code," the relationship between legacy code and beautiful code (and refacotring), and why all software engineers should hope that their code becomes legacy code.

{% hint style="info" %}
In describing cloud+client app architecture, we avoid diving into "client native" frameworks such as React Native or iOS, since these present significant learning-curve and maintainability challenges and all the concepts we need to teach can be embodied in mobile-first HTML/CSS/JavaScript apps.
{% endhint %}

The next five chapters form Part I of the book, which covers SaaS architecture, a server-side SaaS language and framework (Ruby and Rails), and client-side SaaS language and framework (JavaScript and jQuery).

## 2. How to Learn a New Language

This quick introduction will get you up to speed on how to learn any new language and framework, using Ruby, a highly productive scripting language, as an example. We focus on the unique productivity-enhancing features of Ruby that may be unfamiliar to Python programmers, and we omit many details that are well covered by existing materials. As with all languages, becoming truly comfortable with Ruby's powerful features will require going beyond this material; the end of the chapter gives suggested resources.

* **CHIPS 2.5 Ruby Intro:** a gentle intro to Ruby idioms, including running instructor-provided unit tests to check your answers

## 3. SaaS Application Architecture: Microservices, APIs, and REST

Fundamentally, a RESTful SaaS app is a collection of resources and operations on those resources. This chapter examines the basics of the client-server Web architecture for SaaS, which uses HTTP, HTML, and JSON as the mechanisms by which resources are represented and operations on them are carried out. We'll contrast Service-Oriented Architecture and its latest manifestations, microservices and serverless computing, with traditional monolithic SaaS. We'll put all these ideas together by building and deploying a simple SaaS app that plays a letter-guessing-based word game, using the simple Ruby-based framework Sinatra.

* **CHIPS 3.3 HTTP and URIs:** intro to HTTP requests, URIs, and cookies, using `curl` and `netcat` to see raw data
* **CHIPS 3.7 Create and Deploy a Simple SaaS App** de-mystifies the creation of a SaaS app (a simple word-guessing game using Sinatra) including use of an external service, and how to think about RESTfully "wrapping" application logic in SaaS.

## 4. SaaS Framework: Rails as a Model--View--Controller Framework

Rails is a Ruby-based framework that uses three patterns to organize SaaS apps: Model--View--Controller for the app as a whole, Active Record for models backed by a relational database in the persistence tier, and Template View for constructing HTML pages. For conciseness, DRYness and productivity, Rails makes pervasive use of Ruby's reflection and metaprogramming as well as [convention over configuration](https://en.wikipedia.org/wiki/Convention_over_configuration), a design paradigm that automates some configuration based on the names of data structures and variables. Although Rails presents a lot of machinery for the simple examples developed in this chapter, you will quickly \`\`grow into'' these features as your apps become more sophisticated.

* **CHIPS 4.3 ActiveRecord Basics**: write ActiveRecord queries against a provided seeded database.
* **CHIPS 4.5 Rails Routes**: not actually a homework assignment, but a simple app that lets students enter syntactically valid Rails routes and understand the RESTful routes that Rails would generate for them.
* **CHIPS 4.7 Word Guesser on Rails**: use the same Hangperson game logic and Cucumber scenarios as CHIPS 3.7, but scaffolds a walkthrough of how to deploy the app with Rails instead of Sinatra, as an on-ramp understanding the complex Rails framework.
* **CHIPS 4.9 Hello Rails**: create a brand-new Rails app (RottenPotatoes) from scratch, including routes, database setup, using the debugger, and deploying to Heroku.

## 5. SaaS Framework: Advanced Programming Abstractions for SaaS

This chapter explores three sets of mechanisms for DRYing out your code, thereby making it more concise, beautiful and maintainable. Model validations and controller filters centralize what invariants must hold in order for a model object to be valid (for example, a movie must have a nonblank title) or for a controller action to proceed (for example, the user must be logged in as an admin). ActiveRecord Associations use Ruby language features to represent and manipulate relationships among different types of ActiveRecord models, while using relational-database functionality to represent these relationships as foreign-key associations.\
Finally, scopes let you encapsulate different ActiveRecord queries into composable \`\`building blocks'' that you can easily reuse to add new query functionality to your app. In each case, tastefully-chosen language features and framework architecture support DRY and concise app code.

* **CHIPS 5.3 Rails Intro**: enhance RottenPotatoes to filter and sort movie lists.

{% hint style="info" %}
Coming soon: CHIPS 5.3 will be augmented to also add SSO login to RottenPotatoes, and a new CHIPS 5.7 on Associations will add Reviews to RottenPotatoes, where each review is associated with both a movie and a reviewer.
{% endhint %}

## 6. Mobile and Desktop SaaS Clients: JavaScript Introduction

{% hint style="danger" %}
This chapter topically belongs in Part I, but should perhaps be covered later, and can be excluded entirely. Many interesting SaaS apps are possible without JavaScript, and the advice on JavaScript TDD makes more sense if covered after Chapter 8.
{% endhint %}

Proper use of JavaScript enhances the user experience and can make SaaS apps richer and more interactive. The Web's client-side programming language has a bad reputation because most people who use it lack the programming experience to use its unusual features to write beautiful code.\
The approach that Chapter 2 introduced for learning Ruby and Rails is used here to quickly introduce JavaScript, jQuery,and AJAX. The approach to RSpec in Chapter 8 is mirrored in introducing Jasmine for test-driven development in JavaScript.

{% hint style="info" %}
We deliberately avoid introducing "heavyweight" client-side frameworks such as React or Angular because they add significant complexity and learning curve that is unnecessary for many apps, and because our focus is on the cloud (SaaS) aspects of the app.
{% endhint %}

{% hint style="info" %}
Coming soon: CHIPS 6.9 will add AJAX enhancements to RottenPotatoes.
{% endhint %}

The next six chapters form Part II of the book, which covers software development. Each chapter first introduces and explains the Agile approach to the topic, plus a section at the end of the chapter that offers the contrasting approach from the Plan-and-Document perspective.

## 7. Requirements: Behavior-Driven Design and User Stories

The first step in the Agile cycle, and often the most difficult, is a dialogue with each of the stakeholders to understand the requirements. We first derive \w{user stories}, which are short narratives each describing a specific interaction between some stakeholder and the application. Velocity-based iteration planning, supported by tools such as [Pivotal Tracker](https://pivotaltracker.com), use user stories to help estimate the difficulty of the work so as to produce a schedule and how to correct the schedule when actual progress differs from predicted progress. The [Cucumber](https://cukes.info) tool turns these stylized but informal English narratives into acceptance and integration tests. As SaaS usually involves end users, we also need a user interface. We do this with *low-fidelity (Lo-Fi)* drawings of the Web pages and combine them into *storyboards* before creating the UI in HTML. In this chapter you will learn requirements elicitation, cost estimation, project scheduling, and monitoring progress.

* **CHIPS 7.7 Intro to BDD and Cucumber**: write Cucumber features (integration/acceptance tests) to test happy and sad paths of RottenPotatoes.

## 8. Testing: Test-Driven Development

In test-driven development, you first write failing tests for a small amount of nonexistent code and then fill in the code needed to make them pass, and look for opportunities to refactor (improve the code's structure) before going on to the next test case.\
This cycle is sometimes called Red--Green--Refactor, since many testing tools print failed test results in red and passing results in green. To keep tests small and isolate them from the behavior of other classes, we introduce mock objects and stubs as examples of *seams*---places where you can change the behavior of your program at testing time without changing the source code itself.

{% hint style="info" %}
Coming soon: revamped CHIPS 8.5 that scaffolds the process of learning to write RSpec tests.
{% endhint %}

* **CHIPS 8.9 BDD/TDD Cycle:** a complete pass through the BDD and TDD cycle of specifying a feature in terms of stories and then using TDD with RSpec to drive the development and deployment of the feature.

## 9. Software Maintenance: Enhancing Legacy Software Using Refactoring and Agile Methods

Out of every dollar spent on software, 36% is spent on enhancements, 10% on fixing bugs, 11% on adapting to environmental changes such as new library versions or API changes, and 3% on *refactoring* to make the software more maintainable. In total, therefore, about 60% of software expenses is devoted to software maintenance, so your first job is more likely to involve improving existing code than creating a brand-new system from a clean slate. Chapters 7--8 (BDD+TDD) looked at disciplined ways to evolve new code. Although thorough formal documentation of legacy systems may be lacking or inaccurate, the Agile techniques we already know can be pressed into service to help understand the structure of legacy software and create a foundation for extending and modifying it with confidence. We describe what good code looks like and why, and show how to apply refactoring techniques to legacy code both to make it more testable (and therefore modifiable with confidence) and to leave it in better shape than we found it for the next developers.

## 10. Agile Teams

Programming is now primarily a team sport, and this chapter covers techniques that can help teams succeed. *Pair programming, design reviews, and code reviews* can improve software quality. Good version control practices, supported by tools such as Git,\
address code management. Distributed development using branch-per-feature, pull requests, and upstream merging allows \`\`teams of teams'' to collaborate on large projects. We outline successful workflows for small teams that keep everyone in sync and disseminates knowledge about different parts of the codebase to all team members.

* **CHIPS 10.5 Agile Iterations:** Two (or more) full iterations of Agile adding features to an existing (legacy) app

{% hint style="info" %}
**Bluejay**, a tool for scaffolding students through the Agile workflow (claim a story, make a feature branch, request code review via pull request, deliver feature to client) will be made available to instructors soon.
{% endhint %}

## 11. Design Patterns for SaaS Apps

Besides reusability, programmer productivity requires concise, readable code with minimal clutter. In this chapter, we describe some concrete guidelines for making your class architecture DRY and maintainable: the SOLID principles of object-oriented design---Single Responsibility, Open/Closed, Liskov Substitution, Injection of Dependencies, and Demeter---and some design patterns supporting them. We will learn about design smells and metrics that may warn you of violations of SOLID, and explore some refactorings to fix those problems. In some cases, those refactorings will lead us to one of a collection a design patterns---proven \`\`templates'' for class interaction that capture successful structural solutions to common software problems.

## 12. Dev/Ops

Unlike shrink-wrapped software, SaaS developers are typically much closer to post-release operations and maintenance. This chapter covers what your SaaS app should *not* do when released: crash, become unresponsive when it experiences a surge in popularity, or compromise customer data. Since many of these concerns are greatly alleviated by deploying in a well-curated PaaS (Platform-as-a-Service) environment such as Heroku, we focus on how to steward your app to leverage those benefits as long as possible by monitoring to identify problems that interfere with responsive service, addressing those problems with caching and efficient database usage, and thwarting common attacks against customer data.

* **CHIPS 12.8 Exploiting Caching and Indices:** improve the performance of RottenPotatoes by adding database indices to speed up key queries.

## 13. Afterword

In this chapter we give perspectives on the big ideas in this book---Agile, Cloud Computing, Rails, SaaS, and SOA---and show how Berkeley students who have graduated and taken jobs in industry rank their importance.


# Projects

TBD


# Tips from Students

Each offering of the class, we survey students asking what advice they'd give to other students. The top three on this list are stable; the rest of the list varies in ordering, but this ordering is representative.

1. Before coding something that is likely to be a feature used by other SaaS apps (file upload, capability management, and so on), take the time to search for Ruby gems or JavaScript libraries you can use or adapt. Even two hours of searching is less time than it takes to design, code and test it yourself.
2. Taking time to think about the key entity types (models), relationships among them, and how to capture those relationships in a schema using associations and foreign keys. A good design reduces the likelihood of a painful refactoring due to a schema change. (The instructors have found that Class--Responsibility--Collaborator cards, described in the book, can help with this process.)
3. Especially with the larger 6-person teams we use, a 5 or 10 minute daily standup meeting helped tremendously in keeping everyone on track, preventing conflicting or redundant work, and informally sharing knowledge among team members who ran into problems. Teams that met only once a week and supplemented it with online chat or social-networking groups wished they had met more often.
4. Teams that relied heavily on TDD found its greatest value in regression testing: regression bugs were spotted immediately and could be fixed quickly. Teams that didn't commit to TDD had problems with regression when adding features or refactoring. Teams that used TDD also noted that it helped them organize not only their code, but their thoughts on how it would be used ("the code you wish you had").
5. High coverage gave students confidence they weren't breaking things when they added new features; teams with low coverage found their project more brittle when others' changes were merged. High code quality keeps the codebase manageable: the fork-and-pull-request model is valuable in doing constant mini-reviews, and getting a high GPA from CodeClimate "felt great" as well as giving additional assurance.
6. Fine-grained commits and branch-per-feature were essential in preventing conflicts and keeping the main branch clean and deployment-ready.
7. Not everyone paired, but those who did found that it led to higher quality code and avoided silly mistakes that might have taken extra time to debug otherwise.
8. Teams in which one or a pair of developers owned a story had far fewer coordination problems and merge conflicts than teams that stratified by layer (front-end developer, back-end developer, JavaScript specialist, and so on) and also found that all team members understood the overall app structure better and were therefore more confident when making changes or adding features.
9. Lo-fi storyboards were really helpful in working with customer, and enable essential frequent customer feedback: most teams had at least one experience of building something they thought was cool only to realize the customer didn't care for it. Teams that made hi-fi prototypes invested a lot of time only to realize customer didn't like it. In general, a valuable lesson either way is the difficulty of transforming the customer's description into a technical plan---a key lesson of Agile that we wanted the students to learn.
10. "Containerizing" and structuring views using and other elements makes it easy to style them later without spending a lot of time up front to create the prototype. was very useful in quickly getting something presentable. In contrast, Rails scaffolding of views seemed like an appealing shortcut at first, but teams ended up rewriting almost all of those views anyway, suggesting that simple hand-created markup plus Bootstrap is a better path.


# ACM/IEEE Software Engineering Curriculum Guidelines

We explored the 2013 ACM/IEEE Software Engineering curriculum guidelines in depth and found that our material, together with a suitable student project, covers 100% of Core Tier 1, 94% of Core Tier 2, and 66% of the electives in the curriculum guidelines.

This PDF document shows the detailed mapping between each learning outcome in the curriculum guidelines and the corresponding section of the ESaaS textbook.

{% file src="/files/vTZf8CVoqYxOmLyQlOsS" %}


# Supporting course operations

ESaaS was developed and is actively taught at [UC Berkeley](https://teach.saasbook.info/courseware/www.cs.berkeley.edu), where we routinely deal with very large course enrollments.

So we developed a handful of scripts to support operating an ESaaS course at large scale (many hundreds of students), which you'll find in the GitHub repo [esaas/courseware](https://github.com/esaas/courseware). The following pages describe how to use them.

In general, these scripts understand that ESaaS includes both individual student work and team projects. Therefore, for example, the Heroku script can create or delete Heroku app containers both for each student and one per team, plus access for course staff; the GItHub script can manage repos by organizing access according to teams, plus access for course staff; and so on.

**Contributions of additional scripts are welcome,** in the form of pull requests creating a new subdirectory under `scripts/` in the above repo!


# Managing Heroku apps & teams

In 2022, Heroku eliminated their free plan, making it impossible for students to deploy simple ESaaS CHIPS to Heroku without paying a fee.

Heroku/Salesforce is very generous about working with instructors. Although they have a [student program](https://www.heroku.com/students), you may find it easier to contact them to set you up as an instructor by having a special [Heroku team](https://devcenter.heroku.com/articles/heroku-teams) in your account that is used for student coursework. Students still create their (free) Heroku developer accounts, but you can add and remove apps and associated collaborators on your course-related "team" and have those apps centrally billed, and make an arrangement with Heroku to have those charges covered as long as the apps are course-related and you agree to be responsible for the actions of anyone who joins that team.

To make it easier to manage the team, look at [`scripts/heroku-apps`](https://github.com/saasbook/courseware/tree/main/scripts/heroku-apps)for a script that lets you bulk-add and bulk-remove students and apps from your Heroku course-linked team. Its `README.md`has more details.


# Managing GitHub Classroom Repos & Teams

The [`scripts/github-repos`](https://github.com/saasbook/courseware/tree/main/scripts/github-repos) script manages the creation, deletion, and access of GitHub repos for both individual students and teams, for those classes using GitHub Classroom.\
Specifically, given a list of students' email addresses/GitHub usernames and which team number each student belongs to, the script creates/destroys a GitHub repo accessible to all (and only) the members of that team, plus the course staff, for team projects such as CHIPS 10.5 or for an open-ended team projects course.

This works with either GitHub Classroom or a regular non-Classroom GitHub org of which the course staff is/are the owner(s)/admin(s).


