paru
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 【第1日】EverydayRails輪読会合宿(2022GW) (2022\-04\-29\) ###### tags: `Everyday Rails` [EverydayRails輪読会合宿\(2022GW\) ノートまとめ \- HackMD](https://hackmd.io/cXyZTiHOTC-LYhcOYDw3gA) ## 目次 [TOC] ### 司会 - @eatplaynap [タイマー](https://timer.onl.jp/) ### ドライバー ### スタート地点 この版のまえがき から ### ◆P11私が考えるテストの原則 まで(5:50) - @eatplaynap - テストコードは必ずしもDRY原則に従っていなくてもよい - RSpecのテストコードはSpec(仕様)なので、開発者以外の人が読んでも意味が分かるものになっている - RSpecの文法のみについての本だと思っていたのでちゃんとテストそのもののよりよい書き方について教えてくれるのは安心 - @haruguchi-yuma - ブログから始まったんだ - テストは開発者としての自信をつけさせるもの(自信ねぇな、、、) - テスト中は大体祈りをささげてる - @Saki - Rails 5.0の登場と同時に、Railsチームはコントローラのテストを事実上非推奨とした → フィヨルドの課題でもモデルとシステムテストを書いて、コントローラは書かなかった。書かない理由を疑問に思っていたが、非推奨だったためか。 - 書いていて意味があるテストか不安に感じるので、意味のあるテストを自信をもって書きたい! - テストにおいては DRYでないコードは必ずしも悪とは限らない - 理解しやすい日本語訳なので伊藤さんに感謝です🙏 - @fuwa - 一番大事なのはテストが存在すること。信頼性が高くて理解しやすいテストを書きましょう。 - TDD死んじゃったんですかね。。 - 🙏 - @paru871 - Railsの歴史・進化とともにテストの形や捉え方も変化してきて、今RSpecを学ぶのが楽しみだなと思った。 - 「テストはあなたに開発者としての自信を付けさせるものであるべき」と書かれていたので、テスト理論にも興味が湧いた。TDDとBDDの違いなどを体感したい。 - テストは、かなり自分の希望の結果が出るように寄せて書いてしまいがちなので長く信頼されて使われるテストについて考えていきたい。 - @yocajii > Rails 5.0の登場と同時に、Rails チームはコントローラのテストを事実上非推奨としました > > システムテストは RSpec ではないので、本書で使っていたものとまったく同じではありません - RailsやRSpecの発展の経緯があるらしい - @kaneko - テストについてもっと詳しくなりたいと思いました - Rspec初心者にとって良い入門書になるみたいだ - @cafedomancer - 私が久々にテストファーストで**書かずに**作ったアプリケーション - controller test の代わりに書くべきは request spec - @uda - Rail 5.0でコントローラーのテストが非推奨になった - Postmanってなんか聞いたことあるような... - API を叩く GUI ツールですよ ### ◆P12本書の構成 から P22Gemfile まで(6:50) - @eatplaynap - `bin/setup`で全部セットアップできて便利 - Railsのプラクティスのときはまさに「クリックして確認」みたいなことをやってて辛かった - 機能が完成するまでうまく動いているのかチェックできない - @fuwa - 環境構築中です〜ruby3.1.0にしています - テストスイートってあんまり気にしていませんでしたが確かに気になりますね - @haruguchi-yuma - 環境構築! - テストスイートって美味しそう examplesのこと? - `git checkout -b local remote` - @Saki - `db/schema.rb`になぜ変更が生じてしまったか分かってないです... - 環境構築完了して、`git checkout db/schema.rb `→`git checkout -b my-02-setup origin/01-untested`できました! - 読みながら「テストスイート」ってなんだろうと思ってました :cake: > RSpec を使って 自動化されたテストスイート を追加する必要があります。 - test suite - テストの実行単位 - 1つのメソッド = テストケース - テストケースを束ねたものがテストスイート - @yocajii - さっきから何度か出てきている「テストスイート」が何か分からないかも… - rails以外でRSpecを使うときは関連gemを自分で指定する必要があるところを、`gem rspec-rails`はまとめてやってくれるらしい - @uda - まだRuby 3.1.0インストール中... - foremanというgemは`Procfile`ファイルに書き込んでいろんなプロセスを一度に立ち上げることができる - `bin/dev`コマンド使ったことない - @kaneko - 環境構築っていつも苦戦しがち - 手を動かしながらやるのは良い - @paru871 - 環境構築していよいよ始まった感じがして楽しくなってきました! - テストスイートとは、 > ソフトウェアテストの目的や対象ごとに複数のテストケースをまとめたもの。自動化テストにおいては、テストの実行単位となる。  ソフトウェアテスト(動的テスト)の最小単位はテストケースといえるが、実際にテスト作業ではいくつものテストケースを組み合わせることによって不具合をあぶり出したり、確率的に十分なテストを行ったという結論を出したりする。このようなテスト目的やテスト対象に応じて、多数のテストケースを束ねたものをテストスイートという。 [\(備忘録\)Everyday Rails 第2章「RSpecのセットアップ」 \- Qiita](https://qiita.com/jackie0922youhei/items/a27bf5e86e05aac51890) ### ◆P23テストデータベース から P31モデルスペックの途中 まで(7:50) - @eatplaynap - モデルのテストは学習しやすい - モデル=アプリケーションのコアとなる部分だから - RSpecのテストはspecディレクトリ以下に追加する。rails newしたときに自動生成されるtestディレクトリはRSpecを使う場合は消しておく - 早くも脱落者が… - @haruguchi - 環境構築が終わった! ```bash= $ rails new -h -T, [--skip-test], [--no-skip-test] # Skip test files [--skip-system-test], [--no-skip-system-test] # Skip system test files ``` - @uda - ビューはテストしない!! - @saki - `config/application.rb`にgeneratorの設定(ここにはスペックファイル作らない等の設定)が書ける - スペックファイル=テストファイルのこと - ヘルパースペックに何のテストを書くかよく分からないけど後で出てきそう - 「ビューのテストはしない」とは、具体的にどんなテスト?minitestのシステムテストとは違うもの?これから読んでたら分かりそう。 - ビュースペック=ビュー単体のテストで、ボタンが"存在してること"をテストする感じ。 - システムスペック = minitestのシステムテスト。 - たしかにビュースペック単体のテストは書いても意味なさそう。 > システムテスト、結合テスト、機能テストなどでもある程度カバーできるため、ビュー単体でテストしたい場面はあまりありません。ビューはユーザーのニーズなどにより特に変化しやすいパーツなので、ビューのテストが多いと、メンテナンスが大変になりやすいという懸念があります。(現場Rails p.191) :kansha: - @yocajii - よく分からないワードが多いけど進んでいけば分かるかな - ビュースペックというものもあるらしいが使わないらしい。システムスペックでカバーできるらしい。 - ファクトリ?を使ってテストデータを作る時は`fixtures: true`にするらしい。 - @kaneko - 章ごとにブランチ切れば良いの便利だな - rspecの設定とか分からないのでこれから理解していきたい - @paru871 - いよいよテストを書き始める〜! - 確かにビューのテストは書いたことがない。理由を初めて理解できた。システムテストでカバーできる。 - モデルをテストすればアプリケーションのコアとなる部分をテストすることになる ### ◆P31モデルスペックの途中 から P41バリデーションのテストの途中 まで(8:50) #### 確認したい/わからなかったこと ↓自由に記入してください! - P35 テストデータベースコピー? 古いバージョンのRails では、Rake タスクを使って開発用データベースの構造を手作業でテストデータベースコピーにする必要がありました。 - マッチャ?・・・等しいかどうかを検証させるもの - it内でインスタンス作成後に書いてる`user.valid?`が何かよく分からなかった - `be_valid`:「モデルが有効な状態を理解できてるか検証」とはどういう意味?(p37) - `be_xxx`は`xxx?`メソッドが定義されてて、それを実行してる。`true`か`false`を返す - つまり`valid?`メソッドが実行されている。 - [Railsガイド/1.4 valid?とinvalid? https://railsguides.jp/active_record_validations.html#valid-questionmarkとinvalid-questionmark]より、 - **バリデーションが大丈夫であればtrue、通らなければfalseを返す** - つまり、サンプルコードの`be_valid`は、「first_name,las_name,email,passwordのバリデーションが通ったか」を検証している。 - @yocajii - ここでやったバリデーションのテストというのはテストのプラクティスでやらなくていいと言われているものと同じ物を指している?? - [よくある間違いに「modelのvalidationなど」が含まれている理由に | FJORD BOOT CAMP(フィヨルドブートキャンプ)](https://bootcamp.fjord.jp/questions/521) - 同じ - 自作したバリデーションはテストが必要 - TDDでやるならバリデーションを入れ忘れないためにテストを書く意味がある #### それぞれの気づき - @eatplaynap - バリデーションは書き忘れることが多いのでモデルテストを書く意味はある - カスタムバリデーション以外は必要ないかも - 自分でロジックを考えている場合とか - この本の構成をチェリー本が参考にしたという話だったような…?説明→コードの流れがわかりやすい - @uda - テストを失敗させるの大事 - マッチャはいっぱいあって覚えられない - `to_not`より`not_to`のほうがなんとなくしっくりくる - @haruguchi - be_xxxはxxx?メソッドがあってtrueかfalseを返す時使える - be_falsey be_empty be_valid など - `instance.errors[:column]`とした時配列が返ってくるのわかってなくて includeじゃなくてeqにしてすごく時間溶かした記憶がある。 - Rails consoleで挙動確認した方がイメージ湧くかもしれないと思った。 - テストコードは失敗させないと不安 - @yocajii - さっそくテスト用語なのかRSpec用語なのか分からなくて混乱し始めた… - マッチャ - @fuwa - 後半記憶がありません。。。 - マッチャは期待値と実際の値を比較して、一致したorしなかったの結果を返すオブジェクトのこと - @paru871 - テストコードが意図した通りに動いていることを確認・・・わざと失敗させてみる - to をto_not に変えてエクスペクテーションを反転 - アプリケーション側のコードを変更して、テストの実行結果にどんな変化が起きるか確認(モデルのバリデーションを無効にするなど) - - @kaneko - マッチャについて全然知らないことばかりだ - 伊藤さんの記事読もう... - @Saki - マッチャって何だろう🍵 - テストが失敗しているところを先に見る - テストが期待通りに動いているか確認する方法2つ 1. to をto_not に変えてエクスペクテーションを反転させる   2. アプリケーション側のコードを変更(コメントアウトしたり)してテストを動かしてみる - `expect(A).to eq B `は `assert_equal B, A` - 「Expect A to become B.」 = AがBになるように期待する - 🤔 expect構文のほうが、最初ちょっと癖を感じたけど、どっちが期待値でどっちが実際の値か分かりやすそう。人が読みやすい構文。 - バリデーション、viewのhtml機能でつけてモデル側に書くの忘れるときあるのでテストしたほうが良さそう - モデルにバリデーションのテストを書くかは、考え方が違う ### ◆P41バリデーションのテストの途中 からP45インスタンスメソッドをテストする まで(9:50) #### 確認したい/わからなかったこと ↓自由に記入してください! ↓P43 - buildとnewの違い - 親モデルに属する子モデルのインスタンスを新たに生成したい場合に使うメソッド(らしい) - `new`のエイリアスメソッド。↑のような場合に慣習的にこちらを使う。 #### それぞれの気づき - @Saki - チーム開発でシステムテストしか書いたことがなかったので、モデルテストとても勉強になった! - `valid?`,`be_valid`使いこなしたい - エラー文があるかどうかを確認する必要がないテストを書くときは、`インスタンス.valid?`を実行する必要はない - `.build`メソッドとは? - 親モデルに属する子モデルのインスタンスを新たに生成したい場合に使うメソッド。らしい - `new`のエイリアスメソッド的なもの。インスタンス生成しているが、保存はしてない。 - @eatplaynap - インスタンス作成後`インスタンス.valid?`を実行することでバリデーションエラーがあった場合、エラー文情報が付与されて、`インスタンス.error[:last_name]`みたいな形でアクセスできる - エラー文があるかどうかを確認するテストでない場合は、テスト実行前に`インスタンス.valid?`を実行する必要がない - `be_valid`でOK - マイクオフ・スピーカーオフの梅本さんがどういう状態なのか気になる… - 寝てるに1票 :+1: - 😳 - @fuwa - RSpecで期待値と実際の値が等しいかを比較するときは `==` ではなく `eq` を使う - @uda - haruguchiさんの説明わかりやすかった(コンソールでerrorsの中身を確認したやつ) - バリデーションヘルパーにデフォルトのエラーメッセージが用意されている - emailのユニーク制約はdeviseによるもの - @paru871 - 正常系のパターンだけでなく、エラーが発生する条件もテストすることが必要。 - - @kaneko - エラー文をはかせて確認したいときは`valid?`を使えばいいのか - Railsが何をやっているかもっと詳しくなりたいな... - メソッドが裏で何をやっているか確認しながらやると理解が深まるな - @haruguchi-yuma   ```ruby= be_valid valid?を実行しtrueが返ってくることを検証 be_empty empty?メソッドを実行しtrueが返ってくることを検証 be_hoge hoge?メソッドを実行しtrueが返ってくることを検証 ``` ```ruby= expect(user.name).to be 'John Doe' とすると 'John Doe'.equal? 'John Doe'となってfalseになるから expect(user.name).to eq 'John Doe' としないといけない ``` - @yocajii - バリデーションエラーが期待通り発生したかどうか確認するには、エラーメッセージを比較するという考え方がharuguchiさんの説明で理解できました ### ◆P45クラスメソッドとスコープをテストする から P52describe、context、before、after を使ってスペックをDRYにするの途中 まで(10:50) #### 確認したい/わからなかったこと ↓自由に記入してください! - test suitが今のコードでどこを指しているのか分からなかった - bundle execしたときのテスト一式 - describe とcontextが急に出てきたので戸惑った! - example group や example をグルーピングするメソッド - エイリアス、 - 今更ながらexampleがなぜずっと英字のままなのかわからなくなった→テスト1件1件のこと - RSpec の用語だから? ちなみに it も specify も example のエイリアス - example group = describe = context - example = it = specify #### それぞれの気づき - @Saki - `expect(Note.search("message")).to be_empty` の` Note.search("message")`には、一つもヒットしなかった場合`[]`(空の配列)が入る - `be_empty`とは:Array#empty? が真 - describe、context、before、after 〜のあたりから半分寝てました💤後で自習します - コードのコピペをもっと快適にしたいですね🤔 - @eatplaynap - describeとcontextは機能としては同じだけど意味によって使い分ける - 眠すぎる - 最初からいる人が全員意識朦朧としていて途中参加の人が元気 - @uda - ねむい - `before`は`before :each`とも書ける - `describe`はシステムやクラスの機能に関すること、`context`では特定の状態に関することを記述する - vimのインデントについては目がさめたら考える - @kaneko - 文章読んでたけど眠くて何言ってるか分からなくなってた - describeはシステムやクラスの機能に関するアウトラインを記述し、contextは特定の状態を記述する - @cafedomancer - ねてた - describe も context も同じメソッド。名前が違うだけ。状況に応じて使い分ける - be_valid とか be_empty はたしか predicate method を呼び出して true, false をチェックするマッチャだったような? 以下のコードと同じかな。 - search スコープのところは ILIKE を使えばよさそうだけど、そうしていないのはなにか理由があるのかな? (ねてたからよくわからない) - ILIKE 使えるのもしかして PostgreSQL だけ? non-standard なのか - Vim は最強! ```ruby= expect(something.valid?).to be(true) expect(something.empty?).to be(false) ``` - @fuwa - describeとかcontextとかbeforeとかafterを使うとDRYにできる - 途中でトイレに行っていたらついていけなくなりました。。。 - @haruguchi - describeとcontextは雰囲気でやってるな、、、、 - スコープの戻り値はActiveRecord::Relationかな? - そうでした! - ね、 むいぞ! - @paru871 - Rubymine便利だなー - describe とcontext は技術的には交換可能 - describeではクラスやシステムの機能に関するアウトラインを記述 - contextでは特定の状態に関するアウトラインを記述 - このケースであれば、状態は二つあります。一つは結果が返ってくる検索文字列を渡された状態で、もう一つは結果が返ってこない検索文字列が渡された状態です。 - @yocajii - before(:all) と before(:suite) は便利そうだけどbefore(:each)で済むならその方が良い📝 ### ◆P53describe、context、before、after を使ってスペックをDRYにするの途中、コードを実行するところ から  P56モデルスペックの最後 まで(11:50) #### 確認したい/わからなかったこと ↓自由に記入してください! #### それぞれの気づき - @cafedomancer - まとめに大事そうなことが書いてあった - 起きてほしいことと起きてほしくないことの両方をテストすること - 同値分割だけでなく境界値分析もおこなってそれをテストすること - project の uniqueness validation の example はもうあった :joy: :joy_cat: - @uda - 説明文にメソッド名は記述しないほうが好ましい - uniquenessはOKもNGもテストする - scope がついていたので特に両方あったほうがいいなと思いました。単純な uniqueness validation だったら NG なケースだけでも良いかもしれない。 - :fumufumu: - 久しぶりに眠い・寒い・腹減ったの三重苦を味わった - @eatplaynap - 後半部分で目が覚めてきました - 「期待する結果は能動形で明示的に記述」というのはつまりshouldを使わないってことだと理解した - minitestの場合もテスト名はこういうルールで書いたほうがいいのかな? - RSpec 2 ~> 3 にかけて書き方が大きく変わりました。2 のときは something.should ... のように書かれていました。https://qiita.com/awakia/items/d880250adc8cdbe7a32f - @yocajii - vim筋トレありがたいです😂 - ドライバーありがとうございました〜〜🙏 - @Saki - 起きていたのに頭は寝ていました。眠いのかお腹へってるのかもわからん - 大事そう > 境界値テストをすること。もしパスワードのバリデーションが4文字以上10文字以下な ら、8文字のパスワードをテストしただけで満足しないでください。4文字と10文字、そ して3文字と11文字もテストするのが良いテストケースです。 - DRYも大事だが、読みやすさも大事なので、DRYを追求しすぎない - @paru871 - よかじさん、たくさんドライバーやってくださってありがとうございました! - vimの凄さと効率の良さを見せつけられた! - P55のまとめとQ&Aがわかりやすく書かれているので、助かる〜 - @kaneko - DRYは大事だが読みやすさも大事 - 良いときと悪いときの両方をテストする 明日はP56モデルスペックの演習問題、project_spec.rbにlate?メソッドのテストを追加するところから

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully