Skip to main content

GitHub Copilot์„ ์‚ฌ์šฉํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

Copilot์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์œ„ ๋ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ”๋“œ ํ’ˆ์งˆ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

์†Œ๊ฐœ

GitHub Copilot์€ ํ…Œ์ŠคํŠธ๋ฅผ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•˜๊ณ  ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ์—์„œ๋Š” Copilot์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์œ„ ๋ฐ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. Copilot์€ ๊ธฐ๋ณธ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ž˜ ์ˆ˜ํ–‰๋˜์ง€๋งŒ ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—๋Š” ์ข€ ๋” ์ž์„ธํ•œ ํ”„๋กฌํ”„ํŠธ์™€ ์ „๋žต์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์„œ์—์„œ๋Š” Copilot์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…์„ ๋ถ„์„ํ•˜๊ณ  ์ฝ”๋“œ ์ •ํ™•์„ฑ์„ ํ™•์ธํ•˜๋Š” ์‹ค์ œ ์˜ˆ์ œ๋ฅผ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

ํ•„์ˆ˜ ์กฐ๊ฑด

์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Copilot Chat๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

์ด ์„น์…˜์—์„œ๋Š” GitHub Copilot ์ฑ„ํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ Python ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค. ์ด ์˜ˆ์ œ์—์„œ๋Š” Copilot์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋ž˜์Šค BankAccount์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ์ค๋‹ˆ๋‹ค. Copilot์„ ํ”„๋กฌํ”„ํŠธํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์‹คํ–‰ํ•˜๊ณ , ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ์ค๋‹ˆ๋‹ค.

์˜ˆ์ œ ํด๋ž˜์Šค: BankAccount

๊ณ„์ •์˜ ์ž”์•ก์„ ์ž…๊ธˆ, ์ธ์ถœ ๋ฐ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์„ ํฌํ•จํ•˜๋Š” ํด๋ž˜์Šค BankAccount๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. GitHub ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ƒˆ ํŒŒ์ผ bank_account.py๋ฅผ ๋งŒ๋“ค๊ณ  Python์—์„œ ๋‹ค์Œ BankAccount ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

class BankAccount:
    def __init__(self, initial_balance=0):
        if initial_balance < 0:
            raise ValueError("Initial balance cannot be negative.")
        self.balance = initial_balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Deposit amount must be positive.")
        self.balance += amount

    def withdraw(self, amount):
        if amount <= 0:
            raise ValueError("Withdrawal amount must be positive.")
        if amount > self.balance:
            raise ValueError("Cannot withdraw more than the current balance.")
        self.balance -= amount

    def get_balance(self):
        return self.balance

Copilot Chat๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ƒ์„ฑ

Copilot์— ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํฌ๊ด„ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ผ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ตœ์ƒ์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ป์œผ๋ ค๋ฉด ํ…Œ์ŠคํŠธ ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ BankAccount ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กฌํ”„ํŠธ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.

ํ”„๋กฌํ”„ํŠธ:Python์—์„œ BankAccount() ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํฌ๊ด„์ ์ธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ๊ฐœ๋ฐœํ•ฉ๋‹ˆ๋‹ค. ์—์ง€ ์‚ฌ๋ก€, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐ ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ํฌํ•จํ•˜์—ฌ ๊ด‘๋ฒ”์œ„ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃจ๋Š” ์—ฌ๋Ÿฌ ํ…Œ์ŠคํŠธ ๋ฉ”์„œ๋“œ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”„๋กฌํ”„ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ”์œ„: Copilot์ด ๋‹ค์–‘ํ•œ ์ž ์žฌ์  ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ๋ณธ ํ…Œ์ŠคํŠธ ์ด์ƒ์„ ์ƒ์„ฑํ•˜๋„๋ก ํฌ๊ด„์ ์ธ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ๋ช…์‹œ์ ์œผ๋กœ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  • ์‹œ๋‚˜๋ฆฌ์˜ค: ํ”„๋กฌํ”„ํŠธ๋Š” ํ…Œ์ŠคํŠธ์— ๋‹ค์Œ์„ ํฌํ•จํ•˜๋„๋ก ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
    • ์—์ง€ ์‚ฌ๋ก€: ๊ฒฝ๊ณ„ ์กฐ๊ฑด ํ…Œ์ŠคํŠธ(์˜ˆ: ์˜ˆ๊ธˆ ๋˜๋Š” ์ธ์ถœ์— ๋Œ€ํ•œ ์Œ์ˆ˜ ๊ฐ’, ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ž”์•ก๋ณด๋‹ค ๋” ๋งŽ์ด ์ธ์ถœ).
    • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ: ํŠน์ • ์ž˜๋ชป๋œ ์ž‘์—…์ด ๋ฐœ์ƒํ•  ๋•Œ ๋ฐœ์ƒํ•ด์•ผ ํ•˜๋Š” ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ(์˜ˆ: ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ž”์•ก๋ณด๋‹ค ๋” ๋งŽ์€ ๊ธˆ์•ก์„ ์ธ์ถœํ•˜๊ณ  ์Œ์ˆ˜ ๊ธˆ์•ก์„ ์ž…๊ธˆ).
    • ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ: ์ž…๋ ฅ์˜ ์œ ํšจ์„ฑ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฒ€์‚ฌํ•˜๊ณ  ๋ฉ”์„œ๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

Copilot์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‘๋‹ต์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

import unittest
from bank_account import BankAccount

class TestBankAccount(unittest.TestCase):
    def setUp(self):
        self.account = BankAccount()

    def test_initial_balance(self):
        self.assertEqual(self.account.get_balance(), 0)

    def test_deposit_positive_amount(self):
        self.account.deposit(100)
        self.assertEqual(self.account.get_balance(), 100)

    def test_withdraw_within_balance(self):
        self.account.deposit(100)
        self.account.withdraw(50)
        self.assertEqual(self.account.get_balance(), 50)

    def test_deposit_negative_amount_raises_error(self):
        with self.assertRaises(ValueError):
            self.account.deposit(-100)

    def test_withdraw_negative_amount_raises_error(self):
        with self.assertRaises(ValueError):
            self.account.withdraw(-50)

    def test_withdraw_more_than_balance_raises_error(self):
        self.account.deposit(100)
        with self.assertRaises(ValueError):
            self.account.withdraw(200)

    def test_initial_balance_negative_raises_error(self):
        with self.assertRaises(ValueError):
            BankAccount(-100)

if __name__ == '__main__':
    unittest.main()

ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€ ์‹คํ–‰

Copilot์—์„œ ์ƒ์„ฑ๋œ ํ…Œ์ŠคํŠธ ๋„๊ตฌ ๋ชจ์Œ์—๋Š” ํ”„๋กฌํ”„ํŠธ์— ์ง€์ •๋œ ๊ฐ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. BankAccount ํด๋ž˜์Šค์—์„œ ๊ฐ ํ•จ์ˆ˜๋Š” ์˜ˆ๊ธˆ ๋ฐ ์ธ์ถœ๊ณผ ๊ฐ™์€ ์œ ํšจํ•œ ์ž‘์—…๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์Œ์ˆ˜ ๊ธˆ์•ก ๋ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ž”์•ก๋ณด๋‹ค ๋” ๋งŽ์€ ์ธ์ถœ ์‹œ๋„์™€ ๊ฐ™์€ ์—์ง€ ์‚ฌ๋ก€๋ฅผ ํฌํ•จํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฉ๋‹ˆ๋‹ค.

Copilot์ด ํ…Œ์ŠคํŠธ ๋„๊ตฌ ๋ชจ์Œ์„ ์ƒ์„ฑํ•˜๋ฉด ์ƒˆ ํŒŒ์ผ test_bank_account.py์— ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฌผ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กฌํ”„ํŠธ:"unittest ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Python์—์„œ ์ด๋Ÿฌํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•˜๋‚˜์š”?"

Copilot์€ ๋‹ค์Œ bash ๋ช…๋ น์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

python -m unittest test_bank_account.py

ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ„ฐ๋ฏธ๋„ ๋˜๋Š” IDE์— ์ถœ๋ ฅ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•˜๋ฉด BankAccount ํด๋ž˜์Šค๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šฌ๋ž˜์‹œ ๋ช…๋ น

๋˜ํ•œ Copilot์—๊ฒŒ /tests ์Šฌ๋ž˜์‹œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „์ฒด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋ชจ์Œ์„ ์ž‘์„ฑํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. IDE์˜ ํ˜„์žฌ ํƒญ์— ํŒŒ์ผ์ด ์—ด๋ ค ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  Copilot์—์„œ ํ•ด๋‹น ํŒŒ์ผ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. Copilot์—์„œ ์ƒ์„ฑํ•˜๋Š” ํ…Œ์ŠคํŠธ๋Š” ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค๋ฃจ์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ํ•ญ์ƒ ๊ฒ€ํ† ํ•˜๊ณ  ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋Š” ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํŒ

Copilot์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์—์„œ ์•„์ง ๋‹ค๋ฃจ์ง€ ์•Š์€ ์ฝ”๋“œ ํŒŒ์ผ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋„๋ก ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ ํŽธ์ง‘๊ธฐ์—์„œ ์ธ์ ‘ํ•œ ํƒญ์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ธฐ์กด ํ…Œ์ŠคํŠธ ํŒŒ์ผ์„ ์—ด์–ด ์œ ์šฉํ•œ ์ปจํ…์ŠคํŠธ์™€ ํ•จ๊ป˜ Copilot์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Copilot์€ ์‚ฌ์šฉํ•˜๋Š” ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ธฐ์กด ํ…Œ์ŠคํŠธ์™€ ์ผ์น˜ํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

Copilot์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

import unittest
from bank_account import BankAccount

class TestBankAccount(unittest.TestCase):
    def setUp(self):
        self.account = BankAccount()

    def test_initial_balance(self):
        self.assertEqual(self.account.get_balance(), 0)

Copilot์„ ์‚ฌ์šฉํ•˜์—ฌ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋Š” ๊ฒฐํ•ฉ ์‹œ ์‹œ์Šคํ…œ์˜ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” ์™ธ๋ถ€ ์„œ๋น„์Šค NotificationSystem์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํฌํ•จํ•˜๊ณ  ๋ชจ์˜ ํ•ญ๋ชฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ์—ฐ๊ฒฐ ์—†์ด๋„ ์‹œ์Šคํ…œ ๋™์ž‘์„ ํ…Œ์ŠคํŠธํ•˜๋„๋ก BankAccount ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ์˜ ๋ชฉํ‘œ๋Š” BankAccount ํด๋ž˜์Šค์™€ NotificationSystem ์„œ๋น„์Šค ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํ™•์ธํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ์ œ ํด๋ž˜์Šค: Notification Services๊ฐ€ ์žˆ๋Š” BankAccount

์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” NotificationSystem์™€(๊ณผ) ๊ฐ™์€ ์™ธ๋ถ€ ์„œ๋น„์Šค์™€์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํฌํ•จํ•˜๋„๋ก BankAccount ํด๋ž˜์Šค๋ฅผ ์—…๋ฐ์ดํŠธ ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. NotificationSystem์€ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•˜๋Š” ํ†ตํ•ฉ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ ์กฐ๊ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ bank_account.py ํŒŒ์ผ์˜ BankAccount ํด๋ž˜์Šค๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

class BankAccount:
    def __init__(self, initial_balance=0, notification_system=None):
        if initial_balance < 0:
            raise ValueError("Initial balance cannot be negative.")
        self.balance = initial_balance
        self.notification_system = notification_system

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Deposit amount must be positive.")
        self.balance += amount
        if self.notification_system:
            self.notification_system.notify(f"Deposited {amount}, new balance: {self.balance}")

    def withdraw(self, amount):
        if amount <= 0:
            raise ValueError("Withdrawal amount must be positive.")
        if amount > self.balance:
            raise ValueError("Cannot withdraw more than the current balance.")
        self.balance -= amount

        if self.notification_system:
            self.notification_system.notify(f"Withdrew {amount}, new balance: {self.balance}")

    def get_balance(self):
        return self.balance

์—ฌ๊ธฐ์„œ๋Š” Copilot์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์„ธ๋ถ„ํ™”ํ•˜์—ฌ BankAccount ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ๋” ์ž‘๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฌ์šด ์กฐ๊ฐ์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Copilot์—์„œ ์ข€ ๋” ์ •ํ™•ํ•˜๊ณ  ๊ด€๋ จ ์žˆ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กฌํ”„ํŠธ:_ "BankAccount ํด๋ž˜์Šค์˜ deposit ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ชจ์˜ ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ NotificationSystem์„(๋ฅผ) ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๊ณ  ์ž…๊ธˆ ํ›„์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ˜ธ์ถœ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค."_

์ด ํ”„๋กฌํ”„ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒ”์œ„: ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ deposit ํ•จ์ˆ˜์™€ NotificationSystem ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์— ์ค‘์ ์„ ๋‘๊ณ  ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชจ์˜ ํ•ญ๋ชฉ: NotificationSystem์ด(๊ฐ€) ๋ชจ์˜ ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•˜๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ ์š”์ฒญํ•˜์—ฌ ์‹ค์ œ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š๊ณ  ์™ธ๋ถ€ ์‹œ์Šคํ…œ๊ณผ์˜ ์ƒํ˜ธ ์ž‘์šฉ์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.
  • ํ™•์ธ: ํ”„๋กฌํ”„ํŠธ๋Š” NotificationSystem์ด ์ž…๊ธˆ ํ›„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ˜ธ์ถœ๋˜๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ํ†ตํ•ฉ์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ํŠน์ด์„ฑ: ํ”„๋กฌํ”„ํŠธ๋Š” ํ…Œ์ŠคํŠธํ•  ๋ฉ”์„œ๋“œ(deposit) ๋ฐ ํด๋ž˜์Šค(BankAccount)๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

ํŒ

Copilot์ด ์ž˜๋ชป๋œ ํ…Œ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธํ•˜๋ ค๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž…๋ ฅ ๋ฐ ์ถœ๋ ฅ์˜ ์˜ˆ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Copilot์ด ํ•จ์ˆ˜์˜ ์˜ˆ์ƒ ๋™์ž‘์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

Copilot์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

import unittest
from unittest.mock import Mock
from bank_account import BankAccount

class TestBankAccountIntegration(unittest.TestCase):
    def setUp(self):
        self.notification_system = Mock()

    def test_deposit_with_notification(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        account.deposit(50)
        self.assertEqual(account.get_balance(), 150)
        self.notification_system.notify.assert_called_once_with("Deposited 50, new balance: 150")

if __name__ == '__main__':
    unittest.main()

์ƒ์„ฑ๋œ ์ฝ”๋“œ๋ฅผ ์ƒˆ ํŒŒ์ผ test_bank_account_integration.py์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€ ๊ฐœ์„ 

์œ„์˜ ํ”„๋กฌํ”„ํŠธ๋Š” NotificationSystem์ด(๊ฐ€) ์œ ํšจํ•œ ์ž…๊ธˆ์ด ์ด๋ฃจ์–ด์งˆ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๋Š” ๋‹จ์ผ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž…๊ธˆ ์ค‘์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” NotificationSystem์„(๋ฅผ) ํ˜ธ์ถœํ•˜๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์˜ˆ๊ธˆ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์•Œ๋ฆผ ์‹œ์Šคํ…œ์ด ํŠธ๋ฆฌ๊ฑฐ๋˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กฌํ”„ํŠธ:"ํ•จ์ˆ˜๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  NotificationService์ด(๊ฐ€) ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ž˜๋ชป๋œ ์ž…๊ธˆ ๊ธˆ์•ก์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค."

Copilot์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

    def test_deposit_negative_amount_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.deposit(0)
        self.notification_system.notify.assert_not_called()

๊ฐœ์„  ์˜์—ญ์— ๋Œ€ํ•œ ์งˆ๋ฌธ

์ด์ œ ์˜ˆ๊ธˆ์— ๋Œ€ํ•œ ํ†ตํ•ฉ ๊ธฐ๋Šฅ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์ž‘์„ฑํ–ˆ์œผ๋ฏ€๋กœ ํ…Œ์ŠคํŠธ ๋„๊ตฌ ๋ชจ์Œ ๋‚ด์—์„œ ํ–ฅ์ƒ๋œ ๊ธฐ๋Šฅ์„ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ธฐํšŒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ํ…Œ์ŠคํŠธ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋™์•ˆ Copilot์— ์ฝ”๋“œ ๊ฒ€์‚ฌ๋ฅผ ํ‰๊ฐ€ํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ๊ฐœ์„  ์˜์—ญ์„ ์ œ์•ˆํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กฌํ”„ํŠธ: "BankAccount ํด๋ž˜์Šค์™€ NotificationSystem ๊ฐ„์˜ ํ†ตํ•ฉ์— ๋Œ€ํ•œ ์ „์ฒด ๊ฒ€์‚ฌ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์–ด๋–ค ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•˜๋‚˜์š”?"

์ด ์งˆ๋ฌธ์œผ๋กœ Copilot์— ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋ฉด ๊ฐ„๊ณผ๋˜์—ˆ์„ ์ˆ˜ ์žˆ๋Š” ๋ˆ„๋ฝ๋œ ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ์œ ํšจํ•˜๊ณ  ์ž˜๋ชป๋œ ์˜ˆ๊ธˆ์„ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋™์•ˆ ์•„์ง ์ธ์ถœ ๊ธฐ๋Šฅ์„ ๋‹ค๋ฃจ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

Copilot์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—…๋ฐ์ดํŠธ๋œ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์ƒ์„ฑ๋œ ์ฝ”๋“œ ์˜ˆ์ œ๋ฅผ ํ™•์žฅํ•˜๋ ค๋ฉด ํด๋ฆญ
import unittest
from unittest.mock import Mock
from bank_account import BankAccount

class TestBankAccountIntegration(unittest.TestCase):
    def setUp(self):
        self.notification_system = Mock()

    def test_deposit_with_notification(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        account.deposit(50)
        self.assertEqual(account.get_balance(), 150)
        self.notification_system.notify.assert_called_once_with("Deposited 50, new balance: 150")

    def test_deposit_negative_amount_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.deposit(-50)
        self.notification_system.notify.assert_not_called()

    def test_deposit_zero_amount_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.deposit(0)
        self.notification_system.notify.assert_not_called()

    def test_withdraw_with_notification(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        account.withdraw(30)
        self.assertEqual(account.get_balance(), 70)
        self.notification_system.notify.assert_called_once_with("Withdrew 30, new balance: 70")

    def test_withdraw_exceeding_balance_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.withdraw(150)
        self.notification_system.notify.assert_not_called()

    def test_withdraw_negative_amount_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.withdraw(-30)
        self.notification_system.notify.assert_not_called()

    def test_withdraw_zero_amount_raises_error(self):
        account = BankAccount(initial_balance=100, notification_system=self.notification_system)
        with self.assertRaises(ValueError):
            account.withdraw(0)
        self.notification_system.notify.assert_not_called()

    def test_initial_negative_balance_raises_error(self):
        with self.assertRaises(ValueError):
            BankAccount(initial_balance=-100, notification_system=self.notification_system)

if __name__ == '__main__':
    unittest.main()

Copilot์ด ๋งŒ์กฑ๋„์— ๋งž๊ฒŒ ํ…Œ์ŠคํŠธ ์ œํ’ˆ๊ตฐ์„ ์ƒ์„ฑํ•œ ํ›„์—๋Š” ์•„๋ž˜ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

python -m unittest test_bank_account_integration.py

Copilot Spaces๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ œ์•ˆ ๊ฐœ์„ 

Copilot Spaces๋Š” Copilot๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์—…๋ณ„ ์ปจํ…์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ›๋Š” ์ œ์•ˆ์˜ ๊ด€๋ จ์„ฑ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. Copilot์— ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๋” ๋งŽ์€ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋” ๋‚˜์€ ํ…Œ์ŠคํŠธ ์ œ์•ˆ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์„ ํฌํ•จํ•˜๋Š” Space๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ…Œ์ŠคํŠธ ์ค‘์ธ ๋ชจ๋“ˆ(์˜ˆ: payments.js)
  • ํ˜„์žฌ ํ…Œ์ŠคํŠธ ๋„๊ตฌ ๋ชจ์Œ(์˜ˆ: payments.test.js)
  • ๋ˆ„๋ฝ๋œ ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ๊ฒ€์‚ฌ ๋ณด๊ณ ์„œ ๋˜๋Š” ๋ฉ”๋ชจ

์ด Space์—์„œ Copilot์—๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์งˆ๋ฌธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

payments.js์˜ ๋…ผ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ payments.test.js์—์„œ ์–ด๋–ค ํ…Œ์ŠคํŠธ ์‚ฌ๋ก€๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์–ด?

๋˜๋Š”

๊ธฐ์กด ํ…Œ์ŠคํŠธ ๋„๊ตฌ ๋ชจ์Œ์˜ ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ฅด๋ฉด์„œ refund.js์˜ ํ™˜๋ถˆ ๋…ผ๋ฆฌ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ด์ค˜.

Copilot Spaces ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ About organizing and sharing context with GitHub Copilot Spaces์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.