আরএসপেকের বিষয় এবং এর মধ্যে পার্থক্য কী? সেগুলি কখন ব্যবহার করা উচিত?


86

http://betterspecs.org/#subject এর সম্পর্কে subjectএবং এর কিছু তথ্য রয়েছে let। তবে তাদের মধ্যে পার্থক্য সম্পর্কে আমি এখনও অস্পষ্ট। তদ্ব্যতীত, এসও পোস্ট আরএসপেক পরীক্ষায় আগে, চলুন এবং সাবজেক্ট ব্যবহার করার বিরুদ্ধে যুক্তি কী? বলেন এটা হয় ব্যবহার করবেন করাই ভালো subjectবা let। আমি কোথায় যাব? আমি তাই বিভ্রান্ত.

উত্তর:


191

সংক্ষিপ্তসার: আরএসপেকের বিষয়টি একটি বিশেষ ভেরিয়েবল যা পরীক্ষিত বস্তুটিকে বোঝায়। এতে প্রত্যাশা অন্তর্নিহিতভাবে সেট করা যেতে পারে, যা এক-লাইনের উদাহরণগুলিকে সমর্থন করে। এটি কিছু মুশকিল ক্ষেত্রে পাঠকের কাছে স্পষ্ট, তবে অন্যথায় বোঝা শক্ত এবং এড়ানো উচিত। RSpec এর letভেরিয়েবল শুধু প্রখর রৌদ্রে instantiated হয় (memoized) ভেরিয়েবল। এগুলি বিষয়টির মতো অনুসরণ করা ততটা কঠিন নয়, তবে তারা জট বাঁধার পরীক্ষাগুলি নিয়ে যেতে পারে তাই বিচক্ষণতার সাথে ব্যবহার করা উচিত।

বিষয়

কিভাবে এটা কাজ করে

বিষয়টি হচ্ছে পরীক্ষিত বস্তুটি। আরএসপেকের বিষয়টির একটি স্পষ্ট ধারণা রয়েছে। এটি সংজ্ঞায়িত বা নাও হতে পারে। যদি এটি হয় তবে আরএসপেক এটিকে স্পষ্টভাবে উল্লেখ না করে পদ্ধতিতে কল করতে পারে।

ডিফল্টরূপে, যদি বহিরাগত উদাহরণ গোষ্ঠীর ( describeবা contextব্লক) প্রথম আর্গুমেন্টটি কোনও শ্রেণি হয়, আরএসপেক class শ্রেণীর একটি উদাহরণ তৈরি করে এবং বিষয়টিতে নির্ধারিত করে। উদাহরণস্বরূপ, নিম্নলিখিত পাস:

class A
end

describe A do
  it "is instantiated by RSpec" do
    expect(subject).to be_an(A)
  end
end

আপনি নিজের সাথে বিষয়টিকে সংজ্ঞায়িত করতে পারেন subject:

describe "anonymous subject" do
  subject { A.new }
  it "has been instantiated" do
    expect(subject).to be_an(A)
  end
end

আপনি বিষয়টিকে এটি সংজ্ঞায়িত করার সময় একটি নাম দিতে পারেন:

describe "named subject" do
  subject(:a) { A.new }
  it "has been instantiated" do
    expect(a).to be_an(A)
  end
end

এমনকি যদি আপনি বিষয়টির নাম দেন, আপনি এখনও বেনামে উল্লেখ করতে পারেন:

describe "named subject" do
  subject(:a) { A.new }
  it "has been instantiated" do
    expect(subject).to be_an(A)
  end
end

আপনি একাধিক নামযুক্ত বিষয় সংজ্ঞায়িত করতে পারেন। সর্বাধিক সংজ্ঞায়িত নামযুক্ত বিষয় বেনামে subject

তবে বিষয়টি সংজ্ঞায়িত করা হয়েছে,

  1. এটি অলসভাবে ইনস্ট্যান্টেশনযুক্ত। তা হল, বর্ণিত শ্রেণীর অন্তর্নিহিত তাত্ক্ষণিকতা বা ব্লকটির সম্পাদন পাস subjectহওয়া অবধি ঘটে না subjectবা নামকৃত বিষয়টিকে উদাহরণ হিসাবে উল্লেখ না করা পর্যন্ত ঘটে না । আপনি যদি চান যে আপনার স্পষ্ট বিষয়টি আগ্রহের সাথে ইনস্ট্যান্ট করা হোক (এর গ্রুপে উদাহরণের আগে) এটির subject!পরিবর্তে বলুন subject

  2. প্রত্যাশাগুলি স্পষ্টতই এটিতে সেট করা যেতে পারে (কোনও লেখা subjectবা নামকরণের বিষয় ছাড়াই ):

    describe A do
      it { is_expected.to be_an(A) }
    end
    

    এই এক-লাইন বাক্য গঠনটিকে সমর্থন করার জন্য বিষয়টি বিদ্যমান।

কখন এটি ব্যবহার করবেন

একটি অন্তর্নিহিত subject(উদাহরণ গোষ্ঠী থেকে অনুমান করা) বোঝা কঠিন কারণ কারণ

  • এটি পর্দার পিছনে তাত্ক্ষণিক।
  • is_expectedএটি সুস্পষ্টভাবে ব্যবহার করা হোক ( সুস্পষ্ট গ্রহণকারী ব্যতীত কল করে ) বা স্পষ্টভাবে (যেমন subject), এটি পাঠককে সেই বস্তুর ভূমিকা বা প্রকৃতি সম্পর্কে কোন তথ্য দেয় না যার উপর প্রত্যাশা বলা হচ্ছে।
  • ওয়ান-লাইনারের উদাহরণ সিনট্যাক্সের উদাহরণের বর্ণনা নেই ( itসাধারণ উদাহরণ সিনট্যাক্সের স্ট্রিং আর্গুমেন্ট ), সুতরাং উদাহরণটির উদ্দেশ্য সম্পর্কে পাঠকের কেবলমাত্র তথ্যই প্রত্যাশা।

সুতরাং, প্রসঙ্গটি সমস্ত পাঠকের দ্বারা প্রাসঙ্গিকভাবে ভালভাবে বোঝার সম্ভাবনা থাকে এবং উদাহরণের বর্ণনার জন্য সত্যই প্রয়োজন হয় না এমন ক্ষেত্রে অন্তর্নিহিত বিষয়টি ব্যবহার করা কেবলমাত্র সহায়ক । ক্যানোনিকাল কেসটি কাঁটা ম্যাথারগুলির সাথে অ্যাক্টিভেকর্ড বৈধতা পরীক্ষা করছে:

describe Article do
  it { is_expected.to validate_presence_of(:title) }
end

বেনামে প্রকাশিত subject( subjectনাম ছাড়াই সংজ্ঞায়িত ) কিছুটা ভাল, কারণ পাঠক দেখতে পাবেন কীভাবে এটি ইনস্ট্যান্ট হয়, তবে

  • এটি এখনও বিষয়টির ইনস্ট্যান্টেশনটি যেখানে এটি ব্যবহার করা হয়েছে তার থেকে দূরে রাখতে পারে (উদাহরণস্বরূপ একটি উদাহরণ গোষ্ঠীর শীর্ষে এটি ব্যবহার করে এমন অনেক উদাহরণ রয়েছে), যা এখনও অনুসরণ করা শক্ত এবং
  • এতে অন্যান্য সমস্যা রয়েছে যা অন্তর্ভুক্ত বিষয়টি করে।

একটি নামযুক্ত বিষয়টি একটি উদ্দেশ্য-প্রকাশকারী নাম সরবরাহ করে, তবে letআপনি যদি কিছু সময় বেনামী বিষয় ব্যবহার করতে চান তবে একটি পরিবর্তনশীলের পরিবর্তে নামকরণ করা বিষয়টি ব্যবহার করার একমাত্র কারণ এবং বেনামি বিষয়টি কেন বোঝা শক্ত তা আমরা কেবল ব্যাখ্যা করেছি explained

সুতরাং, সুস্পষ্ট বেনামে subjectবা নামযুক্ত বিষয়ের বৈধ ব্যবহারগুলি খুব বিরল

let পরিবর্তনশীল

তারা কিভাবে কাজ করে

let ভেরিয়েবল দুটি পার্থক্য ব্যতীত কেবল নামকরণের বিষয়গুলির মতো:

  • তারা সংজ্ঞায়িত করছি let/ let!পরিবর্তে subject/subject!
  • তারা বেনামে সেট করে না subjectবা প্রত্যাশাকে এটিকে স্পষ্টতই কল করার অনুমতি দেয় না।

এগুলি কখন ব্যবহার করবেন

letউদাহরণগুলির মধ্যে সদৃশতা হ্রাস করতে এটি সম্পূর্ণ বৈধ । যাইহোক, এটি কেবল তখনই করুন যখন এটি পরীক্ষার স্পষ্টতা ত্যাগ করে না। ব্যবহারের সবচেয়ে নিরাপদ সময়টি letযখন letভেরিয়েবলের উদ্দেশ্যটি তার নাম থেকে সম্পূর্ণ পরিষ্কার হয় (যাতে পাঠকের এমন সংজ্ঞাটি খুঁজে না পেতে হয়, যা প্রতিটি উদাহরণ বোঝার জন্য অনেক লাইন দূরে হতে পারে) এবং এটি একইভাবে ব্যবহৃত হয় প্রতিটি উদাহরণে। যদি এই বিষয়গুলির মধ্যে দুটিও সত্য না হয় তবে একটি সাধারণ প্লেইন স্থানীয় ভেরিয়েবলের মধ্যে অবজেক্টটি সংজ্ঞায়িত করার বা উদাহরণস্বরূপ কারখানার পদ্ধতি কল করার বিষয়ে বিবেচনা করুন।

let!ঝুঁকিপূর্ণ, কারণ এটি অলস নয়। যদি কেউ উদাহরণ দলে একটি উদাহরণ যুক্ত করে যা এতে রয়েছে let!তবে উদাহরণটি let!ভেরিয়েবলের প্রয়োজন নেই ,

  • সেই উদাহরণটি বুঝতে অসুবিধা হবে, কারণ পাঠক let!পরিবর্তনশীলটি দেখতে পাবে এবং ভাববে যে উদাহরণটি কীভাবে এবং কীভাবে প্রভাবিত করে
  • উদাহরণটি let!ভেরিয়েবল তৈরি করতে সময় লাগার কারণে এটি হওয়া দরকারের তুলনায় ধীর হবে

সুতরাং let!, যদি মোটামুটি, কেবলমাত্র ছোট, সাধারণ উদাহরণ দলে ব্যবহার করুন যেখানে ভবিষ্যতের উদাহরণ লেখকরা এই ফাঁদে পড়ার সম্ভাবনা কম রয়েছে।

একক প্রত্যাশা-প্রতি-উদাহরণ ফেটিশ

সাবজেক্ট বা letভেরিয়েবলগুলির একটি সাধারণ অতিরিক্ত ব্যবহার রয়েছে যা আলাদাভাবে আলোচনা করার জন্য গুরুত্বপূর্ণ। কিছু লোক তাদের এগুলি ব্যবহার করতে পছন্দ করে:

describe 'Calculator' do
  describe '#calculate' do
    subject { Calculator.calculate }
    it { is_expected.to be >= 0 }
    it { is_expected.to be <= 9 }
  end
end

(এটি এমন একটি পদ্ধতির একটি সাধারণ উদাহরণ যা একটি সংখ্যার প্রত্যাবর্তন করে যার জন্য আমাদের দুটি প্রত্যাশা প্রয়োজন, তবে এই শৈলীতে আরও অনেকগুলি উদাহরণ / প্রত্যাশা থাকতে পারে যদি পদ্ধতিটি আরও জটিল মূল্য দেয় যা অনেক প্রত্যাশার প্রয়োজন হয় এবং / অথবা এর অনেকগুলি পার্শ্ব প্রতিক্রিয়া রয়েছে) সবার প্রত্যাশা দরকার।)

লোকেরা এগুলি করেছে কারণ তারা শুনেছেন যে উদাহরণের জন্য একজনের কেবলমাত্র একটি প্রত্যাশা থাকা উচিত (যা বৈধ নিয়মের সাথে মিশে গেছে যে উদাহরণ হিসাবে কেবলমাত্র একটি পদ্ধতি কল পরীক্ষা করা উচিত) বা তারা আরএসপেকের কৌতূহলের প্রেমে রয়েছে। এটি কোনও অজ্ঞাতনামা বা নামযুক্ত বিষয় বা letভেরিয়েবল সহ হোক না! এই শৈলীতে বেশ কয়েকটি সমস্যা রয়েছে:

  • বেনামে বিষয় উদাহরণগুলির বিষয় নয় - পদ্ধতিটি বিষয়। এইভাবে পরীক্ষা লেখার ফলে ভাষাটি স্ক্রু হয়ে যায়, এটি সম্পর্কে ভাবা শক্ত করে তোলে।
  • সর্বদা এক-লাইনের উদাহরণ সহ, প্রত্যাশার অর্থ ব্যাখ্যা করার মতো কোনও জায়গা নেই।
  • বিষয়টি প্রতিটি উদাহরণের জন্য তৈরি করতে হবে, যা ধীর।

পরিবর্তে, একটি একক উদাহরণ লিখুন:

describe 'Calculator' do
  describe '#calculate' do
    it "returns a single-digit number" do
      result = Calculator.calculate
      expect(result).to be >= 0
      expect(result).to be <= 9
    end
  end
end

17
কি দারুন! +! "একক প্রত্যাশা-প্রতি-উদাহরণস্বরূপ ফেটিশ" এটি স্বর্ণের ওজনের পক্ষে মূল্যবান, তাই বলার জন্য। আমি কখনও এই নিয়মটি খুব ঘনিষ্ঠভাবে অনুসরণ করার প্রয়োজন অনুভব করি নি, তবে এখন যে সমস্ত লোকেরা আমাদের বাকিদের উপর চাপিয়ে দেওয়ার চেষ্টা করে তাদের বিরুদ্ধে আমি এখন সজ্জিত। ধন্যবাদ!
আইকনোক্লাস্ট

4
এছাড়াও, যদি আপনি চান যে আপনার বহুল প্রত্যাশা ব্লকগুলি সমস্ত প্রত্যাশা লাইনগুলি চালিত করে (প্রথম ব্যর্থ হলে চলমান পরিবর্তে) আপনি :aggregate_failuresএকটি লাইনে ট্যাগটি ব্যবহার করতে পারেন it ​"marks a task complete"​, ​:aggregate_failures​ ​do(বইটি রেলস 5 টেস্ট প্রেসক্রিপশন থেকে নেওয়া)
গোলকধাঁধা

4
আমি সমস্ত হাইপস এবং ফেটিশনের বিরুদ্ধেও আছি, "একক প্রত্যাশা-প্রতি-উদাহরণ" মূলত যারা তাদের একক উদাহরণে অনেকগুলি সম্পর্কযুক্ত প্রত্যাশাকে গ্রুপ করতে পছন্দ করেন তাদের পক্ষে। শব্দার্থকভাবে বলতে গেলে, আপনার উদাহরণটি আদর্শ নয়, কারণ এটি কোনও একক সংখ্যার জন্য বৈধতা দেয় না, এটি [0, 9]-তে আসল সংখ্যার জন্য বৈধতা দেয় - যা আশ্চর্য বিস্মিত করে অনেক বেশি পাঠযোগ্য একটি একক প্রত্যাশায় কোড করা যেতে পারে expect(result).to be_between(0, 9)
আন্দ্রে ফিগুয়েরেদো

আপনি শুধুমাত্র একক অঙ্ক সংখ্যা জন্য যাচাই করতে চান, (int [0,9]) এটি আরো উপযুক্ত করতে হবে expect(result.to_s).to match(/^[0-9]$/)- আমি জানি এটা কুৎসিত কিন্তু এটি সত্যিই পরীক্ষা তুমি কি বলছ, অথবা সম্ভবত, ব্যবহার between+ + is_a? Integer, কিন্তু এখানে আপনি পরীক্ষা টাইপ খুব। এবং কেবল let.. এটি উদ্বেগের বিষয় হওয়া উচিত নয় এবং উদাহরণগুলির মধ্যে মূল্যবোধগুলির মূল্যায়ন করা ভাল actually অন্যথায় পোস্টের জন্য +1
আন্ড্রে ফিগুয়েরেদো

আমি আপনার বিপদগুলি সম্পর্কে আপনার ব্যাখ্যাটি পছন্দ করি let!এবং আমার নিজের সতীর্থদের নিজেরাই বোঝাতে পারি নি। আমি এই উত্তর পাঠাতে যাচ্ছি।
দামন আও

5

Subjectএবং letআপনার পরীক্ষাগুলি পরিষ্কার করার এবং গতি বাড়ানোর জন্য কেবলমাত্র সরঞ্জাম। আরএসপেক সম্প্রদায়ের লোকেরা এগুলি ব্যবহার করে তাই আমি সেগুলি ব্যবহার করা ঠিক কি না তা নিয়ে চিন্তা করব না। এগুলি একইভাবে ব্যবহার করা যায় তবে কিছুটা ভিন্ন উদ্দেশ্যে পরিবেশন করা যায়

Subjectআপনাকে একটি পরীক্ষার বিষয় ঘোষণা করার অনুমতি দেয় এবং তারপরে নিম্নলিখিত পরীক্ষার ক্ষেত্রে এটির জন্য পুনরায় ব্যবহার করুন। এটি কোড পুনরাবৃত্তি হ্রাস করে (আপনার কোডটি DRYing করছে)

Letbefore: eachব্লকগুলির বিকল্প , যা পরীক্ষার ডেটা ভেরিয়েবলগুলিকে বরাদ্দ করে। Letআপনাকে বেশ কয়েকটি সুবিধা দেয়। প্রথমত, এটি উদাহরণের পরিবর্তনশীলকে নির্ধারিত না করে মানটিকে ক্যাশে করে। দ্বিতীয়ত, এটি অলসভাবে মূল্যায়ন করা হয়, যার অর্থ এটি কোনও স্পেস না বললে মূল্যায়ন হয় না। এইভাবে letআপনাকে আপনার পরীক্ষাগুলি দ্রুত করতে সহায়তা করে। আমিও মনে করি letপড়া সহজ হয়


1

subjectযা পরীক্ষার অধীনে থাকে তা হ'ল সাধারণত উদাহরণ বা শ্রেণি a letআপনার পরীক্ষায় ভেরিয়েবল বরাদ্দ করার জন্য যা উদাহরণ ভেরিয়েবল ব্যবহার করে অলস বনাম মূল্যায়ন করা হয়। এই থ্রেডে কিছু চমৎকার উদাহরণ রয়েছে।

https://github.com/reachlocal/rspec-style-guide/issues/6

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.