খাঁটি পদ্ধতির জন্য কোনও পরীক্ষা কীভাবে লিখব যা কোনও কিছুই ফেরত না?


13

আমার কাছে ক্লাসগুলির একটি গুচ্ছ রয়েছে যা মানগুলির বৈধতা যাচাই করে। উদাহরণস্বরূপ, একটি RangeValidatorশ্রেণি নির্দিষ্ট মানের মধ্যে একটি মান আছে কিনা তা পরীক্ষা করে।

প্রতিটি ভ্যালিডেটার শ্রেণিতে দুটি পদ্ধতি থাকে: is_valid(value)যা প্রত্যাবর্তন করে Trueবা Falseমানের উপর নির্ভর করে এবং ensure_valid(value)কোন নির্দিষ্ট মান পরীক্ষা করে এবং হয় মানটি বৈধ হলে কিছুই করে না, বা যদি মান পূর্বনির্ধারিত নিয়মের সাথে মেলে না তবে একটি নির্দিষ্ট ব্যতিক্রম ছুঁড়ে দেয়।

এই পদ্ধতির সাথে বর্তমানে দুটি ইউনিট পরীক্ষা যুক্ত রয়েছে:

  • এটি যা একটি অবৈধ মান পাস করে এবং ব্যতিক্রমটি ছুঁড়েছিল তা নিশ্চিত করে।

    def test_outside_range(self):
        with self.assertRaises(demo.ValidationException):
            demo.RangeValidator(0, 100).ensure_valid(-5)
    
  • যা একটি বৈধ মান পাস করে।

    def test_in_range(self):
        demo.RangeValidator(0, 100).ensure_valid(25)
    

যদিও দ্বিতীয় পরীক্ষাটি তার কাজ করে - ব্যতিক্রম ছুঁড়ে ফেলা হলে ব্যর্থ হয় এবং ensure_validকোনও কিছু না ফেললে সফল হয় — যে assertভিতরে কোনও অদৃশ্য নেই তা সত্যই অদ্ভুত দেখাচ্ছে। যে কেউ এই জাতীয় কোড পড়ে তাৎক্ষণিকভাবে নিজেকে জিজ্ঞাসা করবেন কেন এমন একটি পরীক্ষা রয়েছে যা উপস্থিতি কিছুই করছে না বলে মনে হচ্ছে

কোনও মান ফেরত না দেয় এবং এর পার্শ্ব প্রতিক্রিয়া না করে এমন পরীক্ষার পদ্ধতিগুলি পরীক্ষা করার সময় কি এটি এখনকার অনুশীলন? নাকি আমার পরীক্ষা আবার অন্যভাবে লিখতে হবে? অথবা কেবল আমি কী করছি তা ব্যাখ্যা করে একটি মন্তব্য দিন?



11
পেডেন্টিক পয়েন্ট, তবে আপনার যদি এমন কোনও ফাংশন থাকে যা কোনও আর্গুমেন্ট না নেয় (কোনও selfরেফারেন্সের জন্য সংরক্ষণ করে ) এবং কোনও ফলাফল না দেয় তবে তা খাঁটি ফাংশন নয়।
ডেভিড আরনো

10
@ ডেভিড আর্নো: এটি কোনও পেডেন্টিক পয়েন্ট নয়, এটি প্রশ্নের হৃদয়ের ডানদিকে যায়: পদ্ধতিটি সঠিকভাবে পরীক্ষা করা শক্ত কারণ এটি অপরিষ্কার।
Jörg W Mittag

@ ডেভিড আর্নো আরও প্যাডেন্টিক পয়েন্ট হিসাবে, আপনার কাছে "কিছুই না" পদ্ধতি থাকতে পারে (ধরে নিলে "কোনও ফল দেয় না" বোঝানো হয় "রিটার্ন ইউনিট টাইপ" হিসাবে বোঝানো হয় যা voidঅনেক ভাষায় ডাকা হয় এবং নির্বিকার নিয়ম থাকে।) বিকল্পভাবে, আপনি অসীম হতে পারেন লুপ (যা "ফলাফল কোনও ফলাফল না দিয়েও কাজ করে" এর অর্থ আসলে কোনও ফল দেয় না
ডেরেক এলকিনস

যে কোনও ভাষায় টাইপের একটি খাঁটি ফাংশন রয়েছে unit -> unitযা ইউনিটটিকে যাদুগতভাবে বিশেষ-কেসযুক্ত কিছু না করে মানক ডেটাটাইপ হিসাবে বিবেচনা করে। দুর্ভাগ্যক্রমে, এটি কেবল ইউনিটটি দেয় এবং অন্য কিছুই করে না।
ফোশি

উত্তর:


21

বেশিরভাগ পরীক্ষার ফ্রেমওয়ার্কগুলিতে "নিক্ষেপ হয় না" এর একটি স্পষ্ট বক্তব্য রয়েছে, যেমন জেসমিনের রয়েছে expect(() => {}).not.toThrow();এবং নুনিট এবং বন্ধুদেরও রয়েছে।


1
এবং যদি পরীক্ষার কাঠামোর এমন দৃ as়তা না থাকে তবে কোডটি স্ব-বর্ণনামূলক করে তোলে এমন একটি স্থানীয় পদ্ধতি তৈরি করা সর্বদা সম্ভব। ভাল ধারণা.
আর্সেনি মোরজেঙ্কো

7

এটি দৃ language়ভাবে ব্যবহৃত ভাষা এবং কাঠামোর উপর নির্ভর করে। শর্তে বলতে গেলে NUnit, Assert.Throws(...)পদ্ধতি আছে। আপনি তাদের একটি ল্যাম্বদা পদ্ধতি পাস করতে পারেন:

Assert.Throws(() => rangeValidator.EnsureValid(-5))

যা এর মধ্যে কার্যকর করা হয় Assert.Throws। ল্যাম্বডায় কল সম্ভবত একটি try { } catch { }ব্লক দ্বারা মোড়ানো হবে এবং যদি কোনও ব্যতিক্রম ধরা পড়ে তবে দৃ as়তা ব্যর্থ হয়।

যদি আপনার কাঠামোটি এই উপায়গুলি সরবরাহ করে না, আপনি নিজের কলটি মোড়কের মাধ্যমে এটিকে ঘিরে কাজ করতে পারেন (আমি সি # তে লিখছি):

// assert that the method does not fail
try
{
    rangeValidator.EnsureValid(50);
}
catch(Exception e)
{
    Assert.IsTrue(false, $"Exception: {e.Message}");
}

// assert that the method does fail
try
{
    rangeValidator.EnsureValid(50);
    Assert.IsTrue(false, $"Method is expected to throw an exception");
}
catch(Exception e)
{
}

এটি অভিপ্রায়টিকে আরও স্পষ্ট করে তোলে তবে কোডটিকে একটি নির্দিষ্ট পরিমাণে ছড়িয়ে দেয়। (অবশ্যই আপনি এই পদ্ধতিতে কোনও পদ্ধতিতে মোড়ানো করতে পারেন)) শেষে এটি আপনার হাতে থাকবে।

সম্পাদন করা

ডক ব্রাউন যেমন মন্তব্যে ইঙ্গিত করেছেন, বিষয়টি পদ্ধতিটি নিক্ষেপ করার বিষয়টি নির্দেশ করে না, তবে তা ফেলে দেয় না। নুনিতে এটির জন্য একটি দাবিও রয়েছে

Assert.DoesNotThrow(() => rangeValidator.EnsureValid(-5))

1

কেন কোনও দৃ .়তার প্রয়োজন নেই এবং কেন আপনি এটি ভুলে যাননি তা পরিষ্কার করতে কেবল একটি মন্তব্য যুক্ত করুন।

আপনি অন্যান্য উত্তরগুলিতে দেখতে পাচ্ছেন, অন্য যে কোনও কিছু কোড কোডকে আরও জটিল এবং বিশৃঙ্খলাযুক্ত করে তোলে। সেখানে মন্তব্য করার সাথে, অন্যান্য প্রোগ্রামাররা পরীক্ষার উদ্দেশ্য জানতে পারবে।

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


1

আপনি জোর দিয়ে বলতে পারেন যে কিছু পদ্ধতি সঠিকভাবে বলা হয় (বা না ডাকা হয়)।

এই ক্ষেত্রে:

public void SendEmail(User user)
     ... construct email ...
     _emailSender.Send(email);

আপনার পরীক্ষায়:

emailSenderMock.VerifyIgnoreArgs(service =>
    service.Send(It.IsAny<Email>()),
    Times.Once
);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.