Skip to content

Session 2 guide

Selin Jessa edited this page May 7, 2020 · 54 revisions

Code working group - Session 2

Agenda

  • 9-9:45 - wrap-up of Seurat workflow (Marie)
  • 9:45-9:55 - break if needed; questions about Task 1
  • 9:55-10:10 - pull, rebase, merge, and demo (Nic)
  • 10:10-10:20 - R CMD check and unit testing, and intro Task 2 (Selin)
  • 10:20-10:30 - unit test & check demo (Selin)

Links

Task

In this task, we'll create a unit test for the function we created last session.

Outcomes:

  • Understand merging
  • Learn to write unit tests with testthat

Steps:

(The 🌟 marks steps that are great habits to use in your regular day-to-day coding)

  1. [If you didn't do this step during the session...] Merge your changes from last week into the codebase

    • From the develop-private branch, pull changes from the repository: git pull
    • Go to your branch: git checkout issueXXX
    • Rebase to incorporate the latest changes on the develop-private branch: git rebase develop-private
    • Force push your change of history: git push -f origin issueXXX
    • Merge your issue branch into the develop-private branch: git checkout develop-private and then git merge --no-ff issueXXX. In the merge commit, leave the "Merge branch...." message intact, skip a line, and then add a message along the lines of "This closes issue #XXX"
  2. Install some R packages,

    • Required: testthat
    • If not using RStudio: devtools
    • Optional: usethis which has some helpers for package development
  3. Get the latest changes to sandbox.

    • From the develop-private branch, run git pull
    • We'll now go through the process of opening an issue, creating a branch, etc:
      • Open a new issue on github
      • Be sure that you're on the develop-private branch: git checkout develop-private
      • Create a new branch: git checkout -b issue/YYY
  4. Revisiting your function from last session: think of 1 edge case, and add a check & informative error message in the function, using stop() or warning() 🌟 To try out your function on the R command line, you can use the following workflow to load the code in the package.

    • In RStudio: Edit files ---> go to "Build > Load all" to load your functions ---> try out your code ---> rinse and repeat
    • On the R commandline, you can use devtools::load_all()
  5. Create a file to contain your tests, by making a new file in tests/testthat or using usethis::use_test("XXX"). Write at least 2 unit tests for your function from last session, in separate test_that calls. Each test can have more than 1 expectation, and you can explore the expect_*() functions here. Here is a great tutorial on testing: http://r-pkgs.had.co.nz/tests.html

    • A test of a basic use case, to make sure the function works
    • A test of your edge case, to make sure the informative error message is returned
  6. πŸ›‘ Now is a good time to manually check: is your documentation built & your function exported?

    • i.e. is there a corresponding file in the man folder, and when you do library(sandbox), can you access your function?
    • if NOT, go back to Step 5-6 from last week
      • Make sure you have the @export tag in your function's documentation
      • Make sure you ran roxygen2 to create the documentation page, and update the NAMESPACE
  7. Run all tests

    • In RStudio, go to "Build > Test Package"
    • In the R command line, do devtools::test()
    • Make sure they pass πŸ™‚ (Debug until they do...)
  8. Check the package

    • In RStudio
      • First go to "Build > Configure build tools" and add --no-manual to the "Check package" field
      • Then go to "Build > Check Package"
    • In the R command line, do devtools::check(manual = FALSE) *
    • Make sure the package checks with 0 errors (warnings & notes are OK for now, but it's a good idea to make a note of what they are!) πŸ‘πŸ½
  9. Run git status to see what you modified, add all relevant modified files, and commit with an informative message written in the imperative tense, explaining what this commit adds (e.g. Add test for function fibonacci_log()).

  10. Push your commit on your new branch to the remote: git push -u origin issue/YYY (In this command, we're setting up a remote branch issue/YYY to track this one, with the -u flat.)

πŸ›‘ Do not merge yet! At this point, notice that your issue branch should now be at least 1 commit ahead of develop-private

That's it! Next week, we'll incorporate these latest changes into the codebase using pull requests.

* You can also check a package from the bash command line with R CMD check, but devtools adds some handy functionalities, described here.

Resources

Helpful resources for R package development

Helpful Git basics resources

Helpful Git workflow resources

Troubleshooting

Problem: We have a branch with a bunch of commits, but we only want to keep the last one

  • From issue branch, save a commit by creating a new branch to point to that commit: git checkout -b issue/XXX-save
  • Checkout back to issue branch and git reset --hard [sha]
  • Push: git push -f origin issue/XXX

Problem: many commits we want to squash into one

  • With HEAD at the most recent commit, you can squash the last n commits by doing git rebase -i HEAD~n, and change pick to squash on all the lines from 2nd onwards, or f to get rid of the commit message

Problem: we want to change the message of the most recent commit

  • From that branch, do git commit -a, which will fire up the text editor
  • Change the commits and save
  • Force push because we changed the history: git push -f origin issue/XXX

Problem: we want to pull changes on develop-private, but our local branch has diverged

πŸ›‘ Only use this if you want to discard your local changes on develop-private!

  • Checkout to develop-private
  • Reset, so that we're current with the origin branch: git reset --hard origin/develop-private
  • All should be clean with git status